一起学Objective-C - 创建实现类(implementation)2

指定的初始化方法Designated Initializer

注意上篇文章例子中的initWithX:Y:方法,它被标记成为制定的初始化方法。这个概念很重要,因为它确保了类被合适的初始化了。这中指定的初始化方法应该是所有方法中控制最多属性的,其他的初始化方法应该调用这个方法,或者调用其他初始化方法(但是最终还是调用这个方法)。

有指定初始化方法的好处是,一旦子类被创建,它只需要复写指定初始化方法就够了.如果没有这么做的话,外部代码调用初始化方法的时候,只有父类的属性被初始化好了,而子类的则没有。正确的做法是,子类重写这个指定的初始化方法,并调用父类的这个指定初始化方法。

@implementation SuperClass
- initWithA: (int)a
{
  return [self initWithA:a B:0];  // 0 is default value
}


// designated init for SuperClass
- initWithA: (int)a B: (int)b
{
  self = [super init];
  myA = a;
  myB = b;
  return self;
}
@end


@implementation SubClass


// overrides SuperClass's designated init
- initWithA: (int)a B: (int)b
{
  return [self initWithA: (int)a B: (int)b C: (int)c];
}


// designated init for SubClass
- initWithA: (int)a B: (int)b C: (int)c
{
  self = [super initWithA: a B: b];
  myC = c;
  return self;
}
@end

注意,上面的代码中,"self"变量可以被重新定义,这和其他的OO语言不一样。因此我们可以像这样写一个新的构造方法

{
  self = [[self alloc] init];
    // note "self" now refers to the new instance!
  [self setX: 1.0];
  return self;
}

另一点要注意的是Objective-C不强制要求必须首先调用父类的初始化方法。尽管上面的例子那样做的但是那不是必须的 。如果需要的话,你可以在这之前做一些必要的事。

Objective-C中的单例


如果需要的话,有可能初始化方法返回一个已存在的对象而不返回新的对象。可以有几种方法来实现这个。如果你在便捷构造函数中的话可以使用下面的方法

+ new
{
  if (singleton == nil)
    singleton = [[self alloc] init];
  return singleton;
}


如果你要在init里实现的的话,就稍微复杂一些了。

- init
{
  if (singleton != nil)
    {
      RELEASE(self);
      self = RETAIN(singleton);
    }
    else
    {
      singleton = self;
    }
  return self;
}

这里我们显式的释放了当前的实例,然后将它替换成已经存在的singleton。你在使用init方法的返回值时你永远要多加小心。
id anObject = [SomeClass alloc];
  // this is bad:
[anObject init];
  // anObject might have been deallocated!
  // do this instead:
anObject = [anObject init];

上面的例子有问题,因为有一种情况在使用GNUstep librar中的NSConnection时会实际发生,它只允许连接到已经存在的两个端口,所以如果当已经连到一个端口以后你再调用initWithReceivePort:sendPort: ,这个方法会销毁掉新allocate的实例,然后返回当前冲突的实例。

总的来说,最好是使用new而不是init方法来避免创建新的实例,然而因为其他的一些设计约束,可能无法避免要使用init来做。

销毁对象实例Instance Deallocation
- dealloc
{
  RELEASE(anInstanceVariableObject);
  NSZoneFree(NULL, myMemory);
  [super dealloc];
}

这里我们使用了RELEASE宏,并且使用了NSZoneFree方法来释放之前通过NSZoneMalloc或相关方法分配的内存. NULL表示内存是从默认的Zone分配来的.

最后我们调用了 [super dealloc], 在实现dealloc时应该总是这样做,你不用管父类的dellocate,因为它会自己管好自己的。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值