2010-06-14 53 views
1

下面的代碼是否不需要做任何事情?Objective-C iVars /屬性的內存管理技術

@interface MyClass { 
    NSArray *myArray; 
} 

-(void)replaceArray:(NSArray *)newArray; 

@implementation MyClass 

-(void)replaceArray:(NSArray *)newArray { 
    if(myArray) 
    { 
     [myArray release]; 
     myArray = nil; 
    } 

    myArray = [[NSArray alloc] initWithArray: newArray]; 
} 

@end 

如果我做了以下修改:

1)製造myArray的屬性:

@property (nonatomic, retain) NSArray myArray; 

2)改變了分配:

self.myArray = [NSArray arrayWithArray: newArray]; 

將允許我刪除條件?

回答

0

您已經可以擺脫條件。如果數組爲零,那麼你會發送一條消息給零,這是一個無操作。對nil的分配也是沒有意義的。如果您將其設置爲retain屬性,則顯式釋放舊值是錯誤的。

但是,有一種情況下代碼將無法正常工作:當參數是當前值時。在這種情況下,您將釋放當前值,然後嘗試使用已釋放的對象(可能已經被處理)來創建新數組。

3

根本不需要條件;你可以留言nil(包括release),並且什麼都不會發生。你也不需要分配一個新的數組;你可以將retain傳遞給你。如果您擔心實際獲得NSMutableArray,則可以複印。我應該這樣做:

- (void)replaceArray:(NSArray *)newArray 
{ 
    [myArray autorelease]; 
    myArray = [newArray copy]; 
} 

或者,如果你不想使用autorelease,你可以這樣做:

- (void)replaceArray:(NSArray *)newArray 
{ 
    if (myArray != newArray) { 
     [myArray release]; 
     myArray = [newArray copy]; 
    } 
} 
0

成像如下:

MyClass * myObj; 
// init myObj 
NSArray * array = [myObj myArray]; 
[myObj replaceArray:array]; 

在這種情況下, ,myArraynewArray是相同的,這意味着您在發佈後使​​用它。要解決此問題,您只需刪除replaceArray:方法,並將該屬性實施爲@synthesize myArray。因此,上面的代碼更改爲

MyClass * myObj; 
// init myObj 
NSArray * array = [myObj myArray]; 
[myObj setMyArray:array]; 

並且您的問題通過合成實現來解決。

請注意,您是通過創建一個新的陣列設置你的價值:

myArray = [[NSArray alloc] initWithArray: newArray]; 

如果這是你想要的行爲,你應該改變你的屬性定義來複制,而不是保留:

@property (nonatomic, copy) NSArray myArray; 
0

我已經投票了mipadi,因爲他的回答是正確的在你問的問題的上下文中,但爲什麼不只是使用一個屬性,並取消replaceArray:總共:

@interface MyClass { 
    NSArray *myArray; 
} 

@property (copy) NSArray* myArray; 

@end 

@implementation MyClass 

@synthesize myArray; 

-(void) dealloc 
{ 
    [myArray release]; 
    [super dealloc]; 
} 

@end