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