一天,我盯着下面的例程,无法抓住它。我有一个班级,如:
MyClass.h
...
@interface MyClass : NSObject {
NSNumber *myNumber1;
NSNumber *myNumber2;
}
@property (nonatomic, retain) NSNumber *myNumber1;
@property (nonatomic, retain) NSNumber *myNumber2;
@end
和m文件
#import "MyClass.h"
@synthesize myNumber1, myNumber2;
@implementation MyClass
-(id) init {
self = [super init];
NSLog(@"Retain Counts myNumber1: %d, myNumber2: %d", [myNumber1 retainCount], [myNumber2 retainCount]);
myNumber1 = [NSNumber inbitWithint:10];
myNumber2 = [NSNumber inbitWithint:2];
NSLog(@"Retain Counts myNumber1: %d, myNumber2: %d", [myNumber1 retainCount], [myNumber2 retainCount]);
return self;
}
...
我将此类用作全局容器,并使用
从我的应用程序中的每个其他类实例化它MyClass * myGlobals = [[MyClass alloc] init];
===>>>古怪的>>>
运行例程我有以下的facinating控制台输出:
Retain Counts (before) - myNumber1: 0, myNumber2: 0
Retain Counts (after) - myNumber1: 1, myNumber2: 26
怎么可能?
答案 0 :(得分:3)
retainCount
的返回值只有在您编写的类的实例上调用它时才能被认为是准确的,并且您从未曾经将所述实例传递给任何< / strong>系统提供的API。
绝对保留计数是您可能无法控制的实现细节。
目前假设您的代码已被输入,因此错误并非真正出现在原始代码中......
NSNumber缓存公共值的子集。也就是说,对于某些数值,对于检索包装该数字的NSNumber实例的所有请求,都会返回一个NSNumber实例。
答案 1 :(得分:2)
如果这是你的实际代码,它应该根本不起作用,它应该只是崩溃。如果没有,您应该剪切并粘贴您的实际代码。
然而,有几件事。
首先,如果您将NSNumber用作ivar,就像其他任何东西一样,您必须拥有它。如果您打算使用便捷构造函数,则必须使用self上的属性对其进行分配,或者向其发送显式保留消息。
其次,你输入类似initWithInt的内容:here。如果您实际上正在使用该消息,那么您从未实际分配过该号码。您必须将其替换为以下之一:
myNumber1 = [[NSNumber alloc] initWithInt:10]; // explicitly create the number
myNumber1 = [[NSNumber numberWithInt:10] retain]; // take ownership through retain
[self setMyNumber1:[NSNumber numberWithInt:10]]; // use the property accessors to deal with ownership and the convenience constructor to create the number
但是你选择这样做,你必须在某个时候取得对象的所有权。
答案 2 :(得分:2)
你永远不应该看retainCount
因为它无论如何都没有意义。您看到计数为26的原因可能是框架中的某个位置(甚至在您自己的应用程序中)存在NSNumber
的其他实例,这些实例是使用相同的int 2
创建的。 NSNumber
是不可变的,因此优化NSNumber
可能只是为您提供了之前创建的实例。只要你不看retainCount
,这对你来说无关紧要。