这是处理伊娃的正确方法吗?

时间:2012-02-06 09:28:53

标签: objective-c ios

我已经阅读了很多关于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的正确方法吗?

3 个答案:

答案 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

注意:

  1. 您无需在标头中明确声明{...}内的ivars。合成房产时将自动创建它们。显式的ivars是一个遗留概念,从iOS 3开始就不再需要了。

  2. 你不应该在dealloc中使用self.name,因为这会调用getter方法,除了获取ivar之外,这可能会做更多的工作。通常使用getter方法是一种好习惯,但是在dealloc中你应该直接释放ivar

  3. 最好在释放它们之后将ivars设置为nil,但是在dealloc中再次没有必要,因为在dealloc之后没有执行任何代码,因此指针不会被再次引用。

  4. 通常(在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];
}