簡體   English   中英

Iphone - 分配屬性和實例變量

[英]Iphone - Assigning properties and instance variables

好吧,我仍然對目標 c 屬性和實例變量感到困惑。 我在 viewDidLoad 中創建了一個 LocationManager 對象。 一方面 LocationMan 只是一個實例變量,另一方面它被聲明為一個屬性。 看看這些例子:

第一個例子:

Header:

CLLocationManager* _locationMan;

執行:

CLLocationManager* theManager = [[[CLLocationManager alloc] init] autorelease];
_locationMan = theManager;
_locationMan.delegate = self;

第二個例子

Header:

CLLocationManager* _locationMan;
@property (retain, nonatomic) CLLocationManager* locationMan;

執行:

self.locationMan = [[[CLLocationManager alloc] init] autorelease];
self.locationMan.delegate = self;

除了第二個有效而第一個無效之外,這些示例之間有什么區別? memory 管理發生了什么?

您在第一個示例中遇到的問題:

CLLocationManager* theManager = [[[CLLocationManager alloc] init] autorelease];

是由使用autorelease引起的。 autorelease可以看做是:在不久的將來的某個時刻,自動release這個 object。 考慮到autorelease的實現方式,通過釋放池,這通常發生在下一次控制流返回主循環並且釋放池被清空時。

因此,在您的第一種情況下,您正在創建 object 並將其存儲在您的 ivar 中; 但很快它將被釋放,並且由於您沒有在其他任何地方明確保留它,它最終將被釋放。 之后訪問它時,您會收到錯誤消息。 如果您沒有使用autorelease ,一切都會正常工作:

CLLocationManager* theManager = [[CLLocationManager alloc] init]; //-- this is correct
_locationMan = theManager;  //-- because you assign directly to the ivar

在您的第二個示例中,創建是一樣的,這意味着 object 也將被標記為自動釋放。 但是,在這種情況下,您將其分配給具有retain修飾符的屬性。 這意味着 object 將在分配給屬性時自動保留。 因此,當自動釋放實際完成時(大致回到主外觀時),您的 object 的保留計數已經增加了 1; 然后自動釋放它不會使其保留計數 go 為 0,並且不會釋放 object。

你必須清楚地知道的是:

  1. alloc將保留計數設置為 1;

  2. retain屬性將在分配給它們時增加保留計數;

  3. autorelease就像一個延遲發布,因此在此期間(在實際完成發布之前,這意味着在您的方法的 rest 和主循環的調用者中)您可以安全地使用 object,然后它將被釋放。

我在您的代碼中標記了保留的更改,也許它會變得更清楚。

CLLocationManager* theManager = [[[CLLocationManager alloc] init] autorelease];
                                                     ^^^^^ + 1    ^^^^^^^^^^^ - 1 = 0
_locationMan = theManager;

當您的保留降至 0 時,object 不再存在。 下次您嘗試訪問它時,您的應用程序會崩潰。 由於自動釋放,這將在您的自動釋放池耗盡后發生,在您離開當前方法后的未來某個未知時間點。


self.locationMan = [[[CLLocationManager alloc] init] autorelease];
    ^ + 1                               ^^^^^ + 1    ^^^^^^^^^^^ - 1 = +1

您仍然保留了 object。 您必須稍后發布它,但您可以毫無問題地訪問它。

在第一種情況下,您不會通過綜合設置器,它負責保留 object。 在這種情況下,當_locationManager theManager持有任何東西,因此theManager器會被釋放。

第二種情況使用綜合設置器(因為它通過self調用它),因此它在自動釋放后保留theManager

暫無
暫無

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

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