2009-10-01 57 views
0

我有一個委託控制器。在什麼情況下地址上的對象可以更改? (obj-c)

@interface MyConversionController : NSObject { 
    id <ConversionDelegate> _delegate; 
} 
@property (assign) id delegate; 
@end  

@implementation 
@synthesize delegate = _delegate; 
@end 

我收到了Unrecognized selector sent to instance 0x36c4a0錯誤。我在-(void)setDelegate(id)delegate方法上設置了一個斷點,以便我可以觀察傳入我的MyConversionController類的對象。我的setDelegate方法被調用兩次,第一次是地址爲0x36c4a0的對象,我知道符合<ConversionDelegate>協議。第二次調用這個方法的另一個對象也被傳入,這也符合協議。當開始調用委託方法時,方法調用被髮送到第一個對象(0x36c4a0),該對象現在是一些其他類型的對象(如果這有所幫助,通常是CFString__NSFastEnumerationEnumerator)。

有誰知道爲什麼會發生這種情況?


運行malloc_history後,我看到的第一個地址,那是給我找麻煩的人,被分配和釋放的次數之前,我得到它。第二個對象只分配一次。在什麼情況下,指針可以像這樣被重用?

+0

您可以添加代碼分配代理並將其分配給此對象的代碼? – nall 2009-10-01 18:29:18

回答

0

問題是代理人過早地被重新分配。這是很難調試的原因是釋放發生在很久以前我寫的代碼中,並且程序會在發生問題之前退出。編寫新的代碼片段使程序保持打開狀態的時間足夠長,以便其他類可以開始將消息發送到釋放對象。

解決方案:我使用Instruments中的Zombie模塊運行代碼。希望我幾天前完成了這個工作,我在30秒鐘內查看了儀器的輸出結果。

1

您可能希望使用malloc_history來查找該地址處的對象的調用堆棧。不要在終端下面,而你的進程正在運行:

malloc_history <pid> 0x36c4a0 # insert the address in question for the 2nd arg 

您還需要啓用MallocStackLogging(感謝以下庫比什對此有何評論)。

這可以幫助您瞭解該地址處的對象被分配的位置。


此外,您已將代理標記爲assign,不保留,但是,我認爲這適合代表。也就是說,如果它在別處被自動釋放,那麼內存可能會被重用。

你可能會自動釋放委託並分配它嗎?喜歡的東西:

delegate = [[[ConversionDelegateClass alloc] init] autorelease]; 
controller.delegate = delegate 

如果是這樣,則代表將在未來AUTOPOOL釋放被釋放,因爲沒有什麼是保留它,該內存位置將可重新使用。

+0

轉讓是故意的。我的印象是,習慣上類別不會保留他們可能擁有的任何代表,以避免A類和B類彼此保留,以至於無法獲得釋放。 感謝malloc_history提示。 – kubi 2009-10-01 16:21:18

+1

你必須打開'MallocStackLogging'才能使用。 – kubi 2009-10-01 16:33:14

相關問題