2012-03-26 113 views
1

我有一個關於dealloc()和viewDidUnload()方法的快速問題。我注意到很多代碼示例,人們似乎做了不同的事情。iPhone dealloc和viewDidUnload問題

另外,我想補充一點ARC是不是一種選擇。

(1)應如何設置所有屬性爲nil在的dealloc()方法,包括IBOutlets。例如,我應該釋放實例變量[_myArrary版本]並設置self.myArrary = nil。

(2)在viewDidUnload,我想我必須將所有IBOutlets至零,也即在viewDidLoad中創建的任何東西。然而,關於myString,可以說它是在調用viewDidLoad之後的另一種方法中初始化的。我應該把它設置爲零嗎?

如果我宣佈這樣一些特性:

@property (nonatomic, retain) IBOutlet UITableViewCell *myTableCell; 
@property (nonatomic, retain) IBOutlet UILabel *myLabel; 
@property (nonatomic, retain) NSArray *myArrary; 
@property (nonatomic, retain) NSString *myString; 

I synthesize them as such: 

@synthesize myArrary = _myArrary; 
@synthesize myTableCell; 
@synthesize myLabel; 
@synthesize myString; 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    _myArrary = [NSArrary alloc] initWithObjects:@"testObject", nil]; 
} 

- (void)viewDidUnload 
{ 
    self.myArrary = nil; 

    self.myTableCell = nil; 

    self.myLabel = nil; 

    [super viewDidUnload]; 
} 

- (void)dealloc 
{ 
    [_myArray release]; 

    [super dealloc]; 
} 

回答

4
  1. ,如果你在dealloc中設置的屬性/變量到零,因爲一旦該對象被釋放,你不會是它不應該的問題無論如何能夠訪問它們。隨着保持性能,做

    self.varname = nil;

    都將釋放該變量並將其設置爲無。很多人喜歡只發布它們,我寧願將保留屬性設置爲零來保持一致性。

  2. 在viewDidUnload你應該釋放並設置爲無任何不需要的是和將要當視圖加載再次重建。這不是一個嚴格的規則,但是儘可能保持儘可能多的內存是一種很好的做法。如果您的字符串將在viewDidLoad中重新創建,並且在視圖再次加載之前您不需要訪問它,那麼您應該可以釋放它(爲了安全起見,我將它設置爲零)。

    另注,viewDidUnload並不總是得到的dealloc之前調用。所以你應該釋放每個屬性/變量是dealloc,即使它也被釋放並且在viewDidUnload中設置爲nil。爲了確保當你的類被釋放,你會不會泄漏,該代碼你的dealloc功能應該是這樣的:

    - (void)dealloc { 
        [myTableCell release]; 
        [myLabel release]; 
        [_myArray release]; 
        [myString release]; 
    
        [super dealloc]; 
    } 
    

    將它們設置爲nil也是可以接受的,但前提是你使用的合成二傳手,因爲這也釋放變量。

    self.myLabel = nil; 
    

    是好的,但

    myLabel = nil; 
    

    是漏水的。

+0

myTableCell,myLabel和myString的是沒有實例變量的屬性,它不可能說[myTableCell發佈]我知道[self.myTableCell發行]是錯誤的。 – Vikings 2012-03-26 19:37:10

+0

其實'[myTableCell發佈]'是正確的。這些ivars是隱式創建的。 – 2012-03-26 19:46:10

+0

根據您使用的編譯器的版本,這些都可以是有效的。 @synthesize爲你創建一個ivar - 你剛剛將'myArray' ivar重命名爲'_myArray',但其他屬性具有相同名稱的ivars。此外,如果你在'dealloc'你「可以」過關'[self.myTableCell釋放]'只要你不是多線程的......但是,這是它過於複雜 - 現在,使用getter和setter方法正如我前面所描述的那樣,並且徹底閱讀內存管理指南...或者使用ARC - 它也可用於iOS4設備。 – ikuramedia 2012-03-26 19:51:23

2

一般情況下,你希望你的viewDidUnload釋放任何可以在viewDidLoad如果您ViewController尚未在此期間dealloced重建。

dealloc,你需要釋放任何的視圖控制器仍然擁有。你不能假定viewDidUnload被首先調用,所以要防守。

還請記住,將消息發送到nil並沒有什麼壞處 - 但是將發佈發送給不屬於您的對象或將其多次發送給您擁有的對象會帶來很多傷害。

由於您的屬性合成的保留,你可以避免給自己發送release,並且只需使用setter方法將它們設置爲無(self.property = nil),假設你還沒有添加任何額外的課程保留任何地方。

N.B.在你的viewDidLoad中,你明確地將一個新創建的對象分配給你的屬性已經合成的iVar。不要這樣做! 如果另一個對象設置實例化和呈現的屬性,那麼它會泄漏。只有當你確信這是正確的事情時才使用_ivar,並且你已經考慮到了每個邊緣情況。

TL:DR - 使用self.property = nil兩個viewDidUnloaddealloc,從來沒有,除非你首先檢查它已經nil或準備釋放之前的值賦給一個新的對象到_ivar

+0

self.myArray = [NSArrary的alloc] initWithObjects:@ 「的TestObject」,零]示出了當我分析它在Xcode泄漏。 – Vikings 2012-03-26 19:34:50

+0

'self.myArray = [[[NSArray中的alloc] initWithObjects:@ 「的TestObject」,零]自動釋放]'或更簡單地'self.myArray = [NSArray的arrayWithObjects:@ 「的TestObject」,零]' – ikuramedia 2012-03-26 19:37:50

+0

感謝您的響應,你能否詳細說明爲什麼你不應該把這些東西放在_ivar上。我看到很多人在設置數組和其他對象時都這樣做。 – Vikings 2012-03-26 19:40:44

相關問題