2015-07-11 15 views
1

我遇到了NSTimeruserInfo的問題。
the docs蘋果寫道,系統保持強烈的引用定時器(並因此userInfo?),雖然有時當我試圖訪問userInfo對象的部分我得到一個壞訪問異常。 (據我所知,這意味着什麼非常糟糕的事情)NSTimer用戶信息不良訪問異常

事不宜遲,這裏是我的物體看起來像我傳遞給用戶信息:

@interface MyObject 

@property (nonatomic, assign) u_int8_t cmd; 
@property (nonatomic, assign) NSNumber *_id; 

@end 

這裏就是我如何設置定時器:

NSTimer *myTimer = [NSTimer timerWithTimeInterval:10 target:self selector:@selector(someMethod:) userInfo:message repeats:NO]; 
[[NSRunLoop mainRunLoop] myTimer forMode:NSDefaultRunLoopMode]; 

是被觸發,當定時器觸發

-(void) someMethod:(NSTimer *)timer{ 
    MyObject* mObject = [timer userInfo]; 
    u_int8_t cmd = mObject.cmd; // This works 
    NSNumber *_id = mObject._id; // Bad access 
} 

注意的方法:用戶信息我自己不是零。 u_int8_t也沒有或者無論如何。但只要我嘗試訪問NSNumber對象我收到了以下異常(不一定每次):

Crashed: com.apple.main-thread 
EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0x00000000 

如果我添加strong屬性爲NSNumber的對象會發生什麼?這會解決這個問題,爲什麼?爲什麼這個問題首先發生?

+0

您正在訪問與您的標題定義不同的屬性,您是否可以更新您的代碼? –

+0

@TomášLinhart你是對的 - 只需更新它,謝謝。 – user3420815

回答

1

由於NSNumber是你需要使用strong屬性,這是默認的,所以更改@property聲明的對象:

@property (nonatomic) NSNumber *_id; 

而且使用_id作爲標識符是一個糟糕的主意,因爲id是一個Objective-C關鍵字,在某些時候您可能會迷惑自己。

+0

只是爲了解問題:這是否意味着ARC基本上回收userInfo對象的NSNumber對象,但不是對象本身? – user3420815

+1

基本上可以,但不好的一點是它會在'userInfo'字典中保留一個懸掛指針指向'NSNumber'對象,這是導致異常的原因,因爲對象不再有效。 – trojanfoe

+0

非常感謝您的澄清。 – user3420815

1

屬性聲明是錯誤的。 NSNumber是一個對象。屬性類型必須很強或者複製。

@property (nonatomic, copy) NSNumber *_id;