簡體   English   中英

NSNumber怪人……?

[英]NSNumber weirdo …?

現在呆了一天,我盯着下面的例行程序,無法控制。 我有一個像這樣的課程:

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];

=== >>>怪胎>>>

運行例程,我得到以下迷人的控制台輸出:

Retain Counts (before) - myNumber1: 0, myNumber2: 0
Retain Counts (after)  - myNumber1: 1, myNumber2: 26

怎么可能?

不要調用`retainCount`

僅當您在編寫的類的實例上調用retainCount的返回值時,才認為它是准確的, 甚至從未將所述實例傳遞給系統提供的任何 API。

絕對保留計數是您可能沒有任何控制權的實現細節。

暫時假設您的代碼已經鍵入,因此錯誤實際上不在原始代碼中...

NSNumber緩存公共值的子集。 也就是說,對於某些數字值,將為所有請求返回一個NSNumber實例,以檢索包裝該數字的NSNumber實例。

如果這是您的實際代碼,那么它根本不起作用,應該會崩潰。 如果不是,則應剪切並粘貼您的實際代碼。

但是,有兩件事。

首先,如果您將NSNumber用作ivar,則必須擁有它的所有權。 如果計划使用便捷構造函數,則必須使用self的屬性對其進行分配,或者向其發送明確的保留消息。

其次,您在此處鍵入了類似initWithInt:的內容。 如果您實際上正在使用該消息,那么您實際上從未真正分配過該號碼。 您必須將其替換為以下之一:

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

無論您選擇這樣做,都必須在某個時候取得對象的所有權。

您甚至不應該查看retainCount因為它的意義不大。 您看到26的原因是,可能在框架中的某個位置(甚至在您自己的應用程序中)存在其他用相同int 2創建的NSNumber實例。 NSNumber是不可變的,因此作為優化, NSNumber可能只是將您先前創建的實例還給您。 只要您不看retainCount ,對您來說都沒有關系。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM