%d 没有正确显示整数

发布于 2024-08-10 22:37:59 字数 551 浏览 8 评论 0原文

当我尝试写入

NSLog(@"%d", myObject.myId);

myId 为 int 的位置时,控制台给出了一些高数字,例如 70614496。当我使用 @"%@" 时,我收到异常 -[ CFNumber respondsToSelector:]: 消息发送到已释放的实例 0x466c910。 为什么会这样呢?

这是 myObject 的定义:

@interface myObject : NSObject {
int myId;
NSString *title;
}

@property(nonatomic) int myId;
@property(nonatomic, retain) NSString *title;

@end

@implementation myObject

@synthesize myId, title;

- (void)dealloc {
[title release];

[super dealloc];
}

@end

As I try to write

NSLog(@"%d", myObject.myId);

where myId is int, console gives some hight number like 70614496. And when I use @"%@", I get exception -[CFNumber respondsToSelector:]: message sent to deallocated instance 0x466c910.
Why is it so?

Here's definition of myObject:

@interface myObject : NSObject {
int myId;
NSString *title;
}

@property(nonatomic) int myId;
@property(nonatomic, retain) NSString *title;

@end

@implementation myObject

@synthesize myId, title;

- (void)dealloc {
[title release];

[super dealloc];
}

@end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

多像笑话 2024-08-17 22:37:59

Carl 在尝试编译您的代码方面做得很好。关于 %@ 格式说明符的另一句话,因为您的问题似乎暗示了一些混乱。

当您以 NSLog 格式使用 %@ 时,您实际上是在发送参数 description 消息,并打印结果字符串。如果myId是一个int而不是NSObject的实例,它不会响应描述消息。对 int 值使用 %d,对 NSNumber 实例使用 %@。

Carl's doing a good job of trying to get your code to compile. Just another word on the %@ format specifier, since your question seems to imply some confusion.

When you use %@ in an NSLog format, you're actually sending the argument a description message, and printing the resulting string. If myId is an int and not an instance of NSObject, it doesn't respond to the description message. Use %d for int values and %@ for NSNumber instances.

完美的未来在梦里 2024-08-17 22:37:59

这是一个示例,表明如果您的类/对象/实例变量都设置正确,它应该按照您第一次尝试的方式工作:

#import <Foundation/Foundation.h>

@interface MyClass : NSObject
{
  int myId;
}

@property int myId;
@end

@implementation MyClass
@synthesize myId;
@end

int main (int argc, const char * argv[]) {
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  MyClass *myObject = [[MyClass alloc] init];

  myObject.myId = 5;
  NSLog(@"%d", myObject.myId);

  [myObject release];
  [pool drain];
  return 0;
}

您的代码显示您执行与此行相同的操作:

NSLog(@"%d", MyClass.myId);

它甚至无法编译,给出错误:

foundation.m:21: error: accessing unknown 'myId' class method

Here's an example showing that it should work the way you first tried it, if your class/object/instance variable are all set up correctly:

#import <Foundation/Foundation.h>

@interface MyClass : NSObject
{
  int myId;
}

@property int myId;
@end

@implementation MyClass
@synthesize myId;
@end

int main (int argc, const char * argv[]) {
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  MyClass *myObject = [[MyClass alloc] init];

  myObject.myId = 5;
  NSLog(@"%d", myObject.myId);

  [myObject release];
  [pool drain];
  return 0;
}

Your code shows you doing the equivalent of this line:

NSLog(@"%d", MyClass.myId);

Which doesn't even compile, giving the error:

foundation.m:21: error: accessing unknown 'myId' class method
对你再特殊 2024-08-17 22:37:59

鉴于第二条错误消息,我认为 %d 工作正常,但在其他地方,当您应该分配一个 CFNumber 或 NSNumber 到 myID 属性时整数。

Given that second error message, I think the %d is working fine, but somewhere else you’re assigning a CFNumber or NSNumber to the myID property when you should be assigning an integer.

焚却相思 2024-08-17 22:37:59

看来您的 myObject 实例在某个时候自动释放了,并且实际上不再有效。这就是为什么当您尝试将其作为对象取消引用时会看到奇怪的 NSNumber 问题。当您只要求一个整数时,您不会得到任何类型的错误,它只会显示强制转换为整数的指针地址。

要查看 myObject 何时被释放,请尝试将类似的内容添加到类中的 dealloc 方法中:

- (void)dealloc
{
    NSLog(@"dealloc called on %@", self);
    [title release];
    [super dealloc];
}

我敢打赌,在看到 myObject.myID 的日志之前,您会发现它记录了 dealloc。

It looks like your instance of myObject was autoreleased at some time and is no longer actually valid. That is why you see the strange NSNumber issue when you try to dereference it as an object. When you just ask for an integer, you won't get any kind of error, it will just display the pointer's address coerced into an integer.

To see when your myObject gets dealloced, try adding something like this to the dealloc method in your class:

- (void)dealloc
{
    NSLog(@"dealloc called on %@", self);
    [title release];
    [super dealloc];
}

I bet you will find this logging a dealloc before you see the log for your myObject.myID.

心欲静而疯不止 2024-08-17 22:37:59

我会尝试简单地改变这个:

@property(nonatomic) int myId;

到这个:

@property(nonatomic, assign) int myId;

让我知道你的结果,我怀疑 obj-c 在将旧 int 分配给新 int 时做了一些奇怪的事情?

I would try simply changing this:

@property(nonatomic) int myId;

to this:

@property(nonatomic, assign) int myId;

And let me know your result, I suspect that obj-c is doing something funky when assigning an old int to the new int?

心的位置 2024-08-17 22:37:59

查看字符串格式说明符查看如何格式化 NSLog 语句。使用 NSLog 很容易变得懒惰,因为对象有一个内置的 -description 方法,该方法返回格式化字符串。对于缩放器值,您必须使用正确的格式化程序。

由于精度会随着从一个硬件迁移到另一个硬件而发生变化,因此最好养成使用对象转换为日志值的习惯。在这种情况下:

NSLog(@"%@", [[NSNumber numberFromInt:myObject.myId] stringValue]);

这将始终正确打印。


编辑#1:我道歉。写下以上内容时,我正处于睡眠不足的状态。我实际上的目的是警告不要使用简单的 intNSInteger 以及使用 NSNumber numberWithInteger: 进行打印。

考虑以下在 64 位硬件上运行的情况。

int x=pow(2,63);
NSLog(@"x=%d",x); //prints x=2147483647

NSInteger n=pow(2,63);
NSLog(@"n=%d",n); // prints n=-1
NSLog(@"n=%@",[[NSNumber numberWithInteger:n] stringValue]); // prints n=9223372036854775807

在过去的 8 位系统中,您总是会遇到使用 8 位“int”的问题。运行超过 256 次迭代的 for 循环需要 long。使用 32 位 int,您不会看到此类问题,也永远不会养成跟踪 int 变量大小的习惯。

这可能会导致几乎无法追踪的有害错误,因为它们只发生在数据中非常具体和罕见的值中。

为 iPhone(或其他未来的手机/平台)编写意味着在可能高度可变的硬件上编写,就像我们过去必须做的那样。最好尽早养成使用系统和 API 特定定义的习惯。


编辑#2:

其中 myId 是 int,控制台给出一些
高数字,如 70614496。

(1) 如果每次运行时打印不同的数字,那么您在设置它时可能会分配一个指向 int 的指针。 NSLog 正确地将指针的值打印为 int。

(2) 如果它每次打印相同的数字,那么您可能会遇到溢出问题,就像我上面的第一次编辑一样。

无论哪种情况,您都需要查看将值分配给 id 属性的代码,而不是打印它的代码。

Check out the String Format Specifiers to see how to format NSLog statements. It's easy to get lazy with NSLog because objects have a built-in -description method that returns a formatted string. For scaler values, you have to use the proper formatter.

Because precision changes as you move from hardware to hardware, it's better to get in the habit of using object conversions to log values. In this case:

NSLog(@"%@", [[NSNumber numberFromInt:myObject.myId] stringValue]);

This will print correctly always.


Edit#1: I apologize. I was sleep deprived when I wrote the above. What I actually intended was to warn against using a simple int versus NSInteger as well as printing with NSNumber numberWithInteger:.

Consider the following run on 64-bit hardware.

int x=pow(2,63);
NSLog(@"x=%d",x); //prints x=2147483647

NSInteger n=pow(2,63);
NSLog(@"n=%d",n); // prints n=-1
NSLog(@"n=%@",[[NSNumber numberWithInteger:n] stringValue]); // prints n=9223372036854775807

In the old days of 8-bit systems, you ran into problems with problems with using 8-bit 'int' all the time. Running a for-loop with more than 256 iterations required a long. With a 32-bit int you won't see those kinds of issues and will never develop the habit of tracking the size of your intvariables.

This can lead to pernicious bugs that are nearly impossible to track down because they only occur with very specific and rare values in the data.

Writing for the iPhone (or other future mobiles/platforms) means writing on potentially highly variable hardware just like we had to do in the old days. It's best to acquire the habit early of using system and API specific definitions.


Edit#2:

where myId is int, console gives some
hight number like 70614496.

(1) If it prints a different number each time you run, then you're probably assigning a pointer to the int when you set it. The NSLog is correctly printing the value of the pointer as an int.

(2) if it prints the same number each time, the you probably have an overflow issue like in my first edit above.

In either case, you need to look at code where you assign the value to the id property and not where you print it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文