我已经阅读了很多关于getter和setter的主题。我知道它们是什么,为什么有用。不同来源声称发布伊娃的不同方式。这开始我的困惑
@interface CoolClass : NSObject
{
NSString *name;
}
@property (nonatomic, copy) NSString *name;
@end
@implementation CoolClass
@synthesize name = _name;
-(id)init
{
if(super = [self super])
{
self.name = @"Jo";
}
return self;
}
-(void)dealloc
{
[self.name release], self.name = nil;
}
@end
这是释放/释放ivars的正确方法吗?
答案 0 :(得分:2)
您希望在大多数时间使用访问者,但不能在部分构造的状态中使用,因为它们可以negative side-effects。以下是它的完成方式:
- (id)init
{
if((self = [super init])) {
// self.name = @"Jo"; << don't use accessors in initializer
_name = [@"Jo" copy]; << good
}
return self;
}
// added for another variation:
- (id)initWithName:(NSString *)inName
{
if((self = [super init])) {
_name = [inName copy];
}
return self;
}
- (void)dealloc
{
// don't use accessors in dealloc
// don't release the result of a getter (release the result of the retained or copied result)
// [self.name release], self.name = nil;
// instead:
[_name release], _name = nil;
[super dealloc]; << compiler should have warned you about this one
}
注意:在init
的情况下,字符串文字是一个不朽的,如果你复制它并不重要,因为副本只是返回它自己。我的偏好是为了清晰起见而“复制”不朽,虽然这是不必要的。
答案 1 :(得分:1)
以下是我的建议:
@interface CoolClass : NSObject
@property (nonatomic, copy) NSString *name;
@end
@implementation CoolClass
@synthesize name = _name;
-(id)init
{
if(super = [self super])
{
self.name = @"Jo";
}
return self;
}
-(void)dealloc
{
[_name release];
[super dealloc];
}
@end
注意:
您无需在标头中明确声明{...}内的ivars。合成房产时将自动创建它们。显式的ivars是一个遗留概念,从iOS 3开始就不再需要了。
你不应该在dealloc中使用self.name,因为这会调用getter方法,除了获取ivar之外,这可能会做更多的工作。通常使用getter方法是一种好习惯,但是在dealloc中你应该直接释放ivar
最好在释放它们之后将ivars设置为nil,但是在dealloc中再次没有必要,因为在dealloc之后没有执行任何代码,因此指针不会被再次引用。
通常(在dealloc之外),如果你想释放一个ivar,你应该使用这样的setter将它设置为nil:self.name = nil;这将自动释放它并将其设置为零。这相当于[_name release],_ name = nil;
答案 2 :(得分:1)
@interface CoolClass : NSObject
{
NSString *name;
}
你在这里声明了一个实例变量'name';现在没有必要在头文件中声明ivars。只需使用属性并使编译器为您合成ivar。
@property (nonatomic, copy) NSString *name;
这里我们有一个属性声明,指定该对象的副本应该用于赋值,并且先前的值被发送一个释放消息。
在实施中,您想要综合您的属性:
@synthesize name = _name;
此代码告诉编译器为名为“name”的属性生成getter和setter,并使用名为“_name”的实例变量来存储值。所以你现在有两个ivars - 'name'和'_name'。
init方法应该如何:
-(id)init
{
if(self = [super init])
{
name = @"This is ivar declared between {}";
_name = @"synthesized ivar";
}
return self;
}
和dealloc:
-(void)dealloc
{
[name release];
[_name release];
[super dealloc];
}