2010-06-14 68 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