2015-04-07 69 views
0

我在閱讀這個guide時,有一個關於object-c中的手動內存管理的問題。object-c中的手動內存管理

有關問題更加清晰,我將代碼粘貼搞糊塗瞭如下:

// CarStore.m 
- (void)setInventory:(NSMutableArray *)newInventory { 
    if (_inventory == newInventory) { 
     return; 
    } 
    NSMutableArray *oldValue = _inventory; 
    _inventory = [newInventory retain]; 
    [oldValue release]; 
} 

我覺得上面的代碼做了重複操作:

// CarStore.m 
- (void)setInventory:(NSMutableArray *)newInventory { 
    // if we can ensure '_inventory' is different with 'newInventory' 
    if (_inventory == newInventory) { 
     return; 
    } 

    // we can release '_inventory' firstly and safely 
    [_inventory release]; 
    _inventory = [newInventory retain]; 
} 

// CarStore.m 
- (void)setInventory:(NSMutableArray *)newInventory { 
    // if we don't check the equal between '_inventory' and 'newInventory' firstly 
    // then we need temp '_inventory', since '_inventory' and 'newInventory' maybe the same object 
    NSMutableArray *oldValue = _inventory; 
    _inventory = [newInventory retain]; 
    [oldValue release]; 
} 

我不確定在我的思想中是否有一些錯誤,所以請給我一個手。

回答

1

你大部分是正確的,你的任何一個版本都很常見。

雖然中間片段有一個微妙的潛在問題。 newInventory可能與_inventory不同,但釋放_inventory仍會導致newInventory被釋放。這是因爲如果newInventory直接或間接地包含在_inventory中,那麼對newInventory唯一剩餘的強烈參考是_inventory本身。

有又一第三形式,你可以用它避免了一個臨時變量的需要:

- (void)setInventory:(NSMutableArray *)newInventory { 
    [newInventory retain]; 
    [_inventory release]; 
    _inventory = newInventory; 
} 

最後,有可能是原因,您可能要包括平等的檢查,即使它不是嚴格正確的內存管理所必需的。例如,儘管蘋果努力使-retain-release速度很快,但它們不是免費的。所以,如果價值沒有真正改變,跳過它們可能仍然是一種效率提升。另外,您可能希望將其他工作放在您的setter中,例如將視圖標記爲需要顯示或使相關緩存值無效。如果價值沒有真正改變,你可能希望避免這樣做。