23

快速的問題......嗯,我明白,所有的屬性開始都是在Objective-C爲零,並且將消息發送到零什麼也不做,因此,你必須初始化使用[類頁頭] 在裏面];然後將消息發送給新創建的屬性。然而,如果我不發送消息到這個屬性,或者如果我使用self.property = something來設置屬性呢?我是否也需要在這些情況下分配init?此外,UI屬性的起始位置也是零,例如從故事板拖出的UILabel屬性?這些需要alloc init嗎?延遲實例在Objective-C/iPhone開發

感謝所有誰回答

+1

+1非常好的問題。將消息發送到not-yet-alloc/init屬性是OjbC初學者的常見錯誤。 – Philip007 2012-10-03 06:25:52

回答

2

現實的情況是,當你做self.myProperty = [[Class alloc] init],你不初始化你的財產。相反,你正在初始化一個對象,告訴你的屬性(實際上是一個指針)指向。所以如果你已經有了一個分配和初始化的對象,你不必再次分配/ init,你可以做self.myProperty = object;

UI屬性做無從下手爲爲零,這是因爲當您在界面生成器添加元素,認爲擁有您添加的元素和這些對象是爲你自動初始化。這意味着如果您創建IBOutlet並將它們連接到某些屬性,則不必alloc/init。

我希望這是有幫助的。

0

不,您不需要[[Class alloc] init初始化init方法中的屬性。

但是,爲了清楚起見,我鼓勵您在init方法中明確地將它們設置爲Nil。

1

我沒有與故事板的經驗,但我知道,當您通過廈門國際銀行文件,當你告訴一個視圖控制器使用廈門國際銀行文件中的所有對象都正確實例創建對象。所以你不需要擔心在代碼中分配/啓動這些對象。

使用self.property = <something>至於,要看是什麼something是。如果某物是某種現有對象,則不需要在該對象上執行alloc init,因爲self.property = ...語法會調用屬性的setter方法,該方法會將新值適當地保留,複製並賦值給屬性。

現在任何種類的現有對象的可以是一個分配/ init'ed對象,或者從方便方法獲得的自動釋放物體(的NSString的stringWithFormat:例如)。

正如Kaan Dedeoglu指出的那樣,self.property = ...語法指向(並保留)內存中的對象,並且如果它尚未實例化,則由您來初始化該對象。

34

Stunner做了很好的解釋,不需要分配已經創建的init對象。

但是,如果它是一個不存在的對象,你將在哪裏創建它?我提到的一個非常常見的模式是因爲您在文章中提到它,它是懶惰的實例化。

所以你想要一個NSMutableArray屬性。你可以在使用它之前用某種方法分配init,但是你必須擔心「在我需要我的數組之前調用該方法嗎?」或者「我會不小心再次調用它並重新初始化它。」

所以一個故障安全的地方是在屬性的getter中。每次訪問該屬性時都會調用它。

.h 
@property (nonatomic, strong) NSMutableArray* myArray; 

.m 
@synthesize myArray = _myArray; 

- (NSMutableArray*)myArray 
{ 
    if (!_myArray) { 
     _myArray = [[NSMutableArray alloc] initWithCapacity:2]; 
    } 
    return _myArray; 
} 

您訪問的財產,它說,每次「是否存在myArray的?如果不是,創建它。如果是的話,只返回我有什麼。」

此設計模式帶來的另一個好處是,您不需要創建資源,直到您需要它們,而不是一次創建它們,比如說,當您的視圖控制器加載或您的應用程序啓動時,這取決於需求,可能需要幾秒鐘。

+4

好的迴應,但我不同意在getters中實例化ivars,因爲這會查詢對象是否存在不可行。相反,我建議你在setter中進行實例化,因爲你確實知道你設置的ivar是否不存在,你希望它存在以便它可以被設置爲一個值。因此,在調用setter時,永遠都不會希望它存在,而當調用getter時,情況並非總是如此。 – Stunner 2012-08-02 02:51:12

+0

如果我可以添加到這麼晚......如果屬性具有「複製」屬性,您是否需要將其添加到setter中?因爲它已經獲得了要使用的副本? – ScottyB 2014-03-06 16:36:00