NSInteger设置为0但返回nil

12

我在我的类中有一个NSInteger,像这样:

在@interface中:

NSInteger currentRow;    

@property (assign) NSInteger currentRow;
在 @implementation 中:
@synthesize currentRow;

执行[self setCurrentRow:0]似乎运行正常,但是使用[self currentRow]返回null,不确定原因。使用断点时,可以看到currentRow的值为0,所以已经成功设置,但我无法检索该值。

3个回答

17

在Objective-C中,重要的是要区分对象和原始类型。

对象总是作为指针存储的,它是对象在内存中的位置。指针只是一个数字。使用NSLog,可以使用%p查看此值。您也可以在调试器中显示它,例如:print myObject。指针显示为十六进制数字,带有0x前缀。nil本质上是位置零(0x0000)。当您分配任何类型的对象时,将获得一个非零的指针。当您将对象分配给变量时,实际上只是复制内存地址,而不是复制对象。使用NSLog,可以使用%@打印对象的description。在调试器中,可以这样使用:print-object myObject

原始类型,如NSInteger,不是对象。通常情况下,您只需存储值,而不是存储指针。当您分配NSInteger变量时,将复制其值。可以使用print在调试器中查看该值。或者像这样:NSLog("%ld", (long)currentRow)。当您分配原始类型时,将复制其值。不要在原始类型中使用%@print-object,因为它们期望对象。

(我说“通常情况下只需存储值”,因为您也可以将指针引用到原始类型。但在您的情况下,这并不是必需的。)

[self currentRow]返回0,就像您设置的那样。(此外,由于Objective-C保证实例变量的初始化,即使您没有设置它,它也会返回0。)

问题在于您期望一个对象的指针。如何修复您的代码取决于您如何使用它:

  • 如果你正在使用 print-object currentRow,请改为 print currentRow
  • 如果你正在使用 NSLog("%@", currentRow),请改为 NSLog(%"ld", (long)currentRow)
  • 如果你在其他地方使用了 currentRow,并需要对象类型,请将实例变量和属性类型更改为 NSNumber *。你可以使用 [self setCurrentRow:[NSNumber numberWithInt:0]] 对其进行设置。

6

NSInteger并非对象类型,它是typedef为int或类似类型的。因此,如果您将currentRow设置为0,然后尝试获取它,null(又称0)就是完全正确的值。


这是一个分配而非保留属性,因此它应该可以与非对象类型一起使用。 - Mattias Wadman
而且它还能正常工作!在内存中,null和0的实际值是相同的。尝试使用[self setCurrentRow:42],然后您会发现[self currentRow]返回42,只需确保将结果分配给NSInteger而不是对象即可。 - secondcitysaint
只要您将非对象属性定义为“assign”,使得synthesize跳过保留/释放操作,那么使用这些属性是完全有效的。 - Mattias Wadman

4

getter方法将被合成为- (NSInteger)currentRow,所以它应该能够很好地工作。但是如何检查它是否起作用?使用NSLog(@"%@", ...)吗?那么你应该使用%d

如果您想要它成为一个对象,您应该使用NSNumberretain属性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接