Objective-C IVAR/properties的内存管理技术

Objective-C IVAR/properties的内存管理技术,objective-c,memory,properties,Objective C,Memory,Properties,下面的代码是否做了一些不必要的事情 @interface MyClass { NSArray *myArray; } -(void)replaceArray:(NSArray *)newArray; @implementation MyClass -(void)replaceArray:(NSArray *)newArray { if( myArray ) { [myArray release]; myArray = nil; }

下面的代码是否做了一些不必要的事情

@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];

这允许我删除条件吗?

您已经可以删除条件了。如果数组是nil,那么您将向nil发送一条消息,这是一个不可操作的操作。对nil的赋值也是毫无意义的。如果将其设置为
retain
属性,则显式释放旧值是错误的


但是,有一种情况下,该代码无法正常工作:当参数为当前值时。在这种情况下,您将释放当前值,然后尝试使用释放的对象(可能已经解除分配)创建新数组。

您根本不需要条件;您可以发送消息
nil
(包括
release
),但不会发生任何事情。您也不需要分配新数组;您可以保留传递给您的文件。如果您担心实际会得到一个
NSMutableArray
,您可以制作一个副本。我会这样做:

- (void)replaceArray:(NSArray *)newArray
{
    [myArray autorelease];
    myArray = [newArray copy];
}
或者,如果您不想使用自动释放,可以执行以下操作:

- (void)replaceArray:(NSArray *)newArray
{
    if (myArray != newArray) {
        [myArray release];
        myArray = [newArray copy];
    }
}
对以下各项进行成像:

MyClass * myObj;
// init myObj
NSArray * array = [myObj myArray];
[myObj replaceArray:array];
在本例中,
myArray
newArray
是相同的,这意味着您将在发布后使用它。要解决此问题,只需删除
replaceArray:
方法,并将属性实现为
@synthesis myArray
。因此,上面的代码更改为

MyClass * myObj;
// init myObj
NSArray * array = [myObj myArray];
[myObj setMyArray:array];
通过综合实现,您的问题得到了解决

请注意,您正在通过创建新数组来设置值:

myArray = [[NSArray alloc] initWithArray: newArray];
如果这是您想要的行为,则应将特性定义更改为“复制”,而不是“保留”:

@property (nonatomic, copy) NSArray myArray;

我投票支持mipadi,因为他的答案与您提出的问题是正确的,但为什么不使用一个属性并删除replaceArray:总之:

@interface MyClass {
   NSArray   *myArray;
}

@property (copy) NSArray* myArray;

@end

@implementation MyClass

@synthesize myArray;

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

@end