2012-08-13 101 views
2

編輯:我真的很抱歉。我編輯了我在帖子中發出的令人困惑的錯誤。代表並保留週期?

我在WhereamiViewController.h宣佈這些ivars

CLLocationManager *locationManager; 
IBOutlet MKMapView *worldView; 
IBOutlet UITextField *locationTitleField; 

作者寫道,由於WhereamiViewController擁有locationManagerlocationManager's代表是WhereamiViewControllerlocationManager代表必須在WhereamiViewController'sdealloc方法,因爲委託是設置爲nilassigned而不是weak。在.xib文件worldViewlocationTitleField設置爲委託File's Owner,但爲什麼不需要將這兩個代表設置爲nil當他們都是assign而不是weak

PS:它使用ARC

+0

這可能是「大書呆子」書的預ARC版本,對吧? – dasblinkenlight 2012-08-13 15:38:55

回答

0

那麼你需要將它設置爲nil只是作爲一種預防措施。我有困惑嗎?讓我解釋。

的設置nil,真可謂無關retainrelease週期,它只是避免locationManager發送委託調用到控制器。例如,如果locationManager是您的控制器發佈時的更新位置,則locationManager仍將delegate引用設置爲您的視圖控制器,將使用位置參數調用該委託。

但由於您的控制器已被釋放,調用將導致內存訪問不良。

但是,如果將其設置爲nil,則不會拋出異常,因爲nil指針的操作符沒有影響。

+0

感謝您的回答!你會說我需要爲所有委託對象採取這種預防措施嗎?比如UITextField和MKMapView? – stumped 2012-08-13 18:18:20

+1

好吧,不是真的。此度量適用於像locationManager那樣在後臺運行的服務。就UITextField而言,只要用戶可以與它們交互,就可以發送委託調用,只要用戶在屏幕上,用戶只能在屏幕上進行交互,並且如果他們在屏幕上,您的ViewController就會處於良好狀態=) – tGilani 2012-08-14 06:16:28

2

locationManager must be set to nil in the WhereamiViewController's dealloc method

CLLocationManager不保留其委託。即使它在dealloclocationManager設置爲nil將無助於打破保留週期,因爲一擋週期會導致dealloc從來沒有被調用。還需要一些其他事件來中斷保留週期,例如解除/彈出視圖控制器。

但爲什麼不需要將這兩個設置爲零?

如果t記錄爲類不保留委託,那麼您不必擔心保留週期。有時候,這些文檔來自僅查看頭文件並尋找assign而不是strongretainCLLocationManager不保留其代表,因此您不必將locationManager指定爲nil。但是,如果該locationManager仍然可以接收事件之後你的類被釋放,你應該在dealloc方法其委託設置爲nil,防止回調類被釋放後。

- (void)dealloc 
{ 
    //Prevent callbacks after dealloc 
    //Useful if locationManager is a singleton or used elsewhere 
    locationManager.delegate = nil; 

    [locationManager release]; //If not ARC 
    [super dealloc];//If not ARC 
} 
0

locationManager必須設置在WhereamiViewController的dealloc方法爲零。

這並不做任何事情。

如果你正在使用手動引用計數,它應該是在WhereamiViewController的dealloc中發佈的(因爲WhereamiViewController擁有它)。如果您有一個包含locationManager實例變量的屬性,那麼只要該屬性是一個retain屬性,就可以將該屬性設置爲dealloc中的nil以實現相同的效果。但是,蘋果通常不鼓勵在dealloc中使用屬性。

如果您正在使用ARC,編譯器將盡一切爲你。

你應該在WhereamiViewController的dealloc中做什麼,是將位置管理器的委託設置爲nil,因爲如果位置管理器在dealloc之外存活,你不希望它將委託消息發送到不存在的WhereamiViewController。

同樣,如果CLLocationManager的委託是弱引用,那麼使用ARC,可以爲您完成nilling。

但爲什麼不需要將這兩個設置爲零?

他們沒有,但同樣的推理適用於他們的代表,當他們的代表被釋放。