在内存管理、自定义子类和数组方面,我对为自己的子类编写自定义init方法的正确方法感到困惑。如果我有这样的属性:
@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSMutableArray *array;
@property (nonatomic, retain) SomeSubclassOfNSObject *object;
@interface SomeSubclassofNSObject
@property (nonatomic, retain) NSString *category;
如何编写init方法?
你做什么:
initWithName:(NSString *)aName object:(SomeSubclassOfNSObject *)anObject {
if (self = [super init]) {
self.name = aName; // or do you do name = aName or name = [aName copy] autorelease] or name = [NSString alloc] initWithFormat:@"%@", aName]
self.object = anObject; // do I need to make a copy of this object so they don't point to the same object?
// loop through NSMutableArray and copy the objects?
// not really sure what to do for arrays.
}
return self;
}
-
在大多数情况下,我建议使用
self.name = aName;
,因为这会利用生成的setter,因此保留计数会隐式递增。这意味着无论init
的调用方随后对aName
做什么,您的引用都是安全的。这同样适用于dealloc对应项:只需编写self.name = nil;
和done。如果您提供
NSMutableString
,情况会有所不同,因为类内部的更改会影响其他类对此的引用。但从设计角度来看,只有当您有意操纵可变字符串时,才应将其用作参数。 -
self.object = anObject;
:这取决于你想要什么。如果所有的类都指向同一个对象,不要进行复制(我认为这通常正是您想要的)。在某些情况下,深入复制可能是合理的。 -
数组:在init方法中需要类似
array = [[NSMutableArray alloc] init];
的东西。之后,您添加的每个对象的保留计数都将自动递增,即您不能对添加的对象本身调用retain。就像在2中一样。在某些情况下,您可能真的想要某个源数组的对象的副本。好吧,但这种情况很少发生。更常见的情况是,您有一个现有的数组,并且想要它的子数组或特殊排序的版本。所以你得到了一个新的数组,但元素相同。
这是简短的回答。更多信息请访问:
高级内存管理编程指南
声明属性