在Objective-C中,当init方法设置self时,原始对象会发生什么?

时间:2010-08-10 03:14:49

标签: objective-c cocoa-touch inheritance class initialization

我有三个Objective-C类:

@interface ClassA : NSObject{
     IBOutlet id<ClassAProtocol>delegate
     //other instance variables
}

//methods
@end

@interface ClassB : ClassA{
     //instance variables
}

//methods
@end

@interface ClassC : ClassA{
     //instance variables
}

//methods
@end

我的目标是,当在代码或InterfaceBuilder中调用ClassA的实例时,实际创建了ClassBClassC的实例。它是ClassB还是ClassC取决于ClassAProtocol对象实现的delegate中方法的返回值。

@implementation ClassA

static BOOL _initFromSubclass = NO;

-(id)init{
     if(_initFromSubclass){
          _initFromSubclass = NO;
          self = [super init];
     }else {
          _initFromSubclass = YES;
          if([delegate shouldInitClassB]){
                self = [[ClassB alloc] init];
          }else{
                self = [[ClassC alloc] init];
          }
     }

     return self;
}

//other methods
@end

这不能按我想要的方式工作,因为在init调用时,委托(在Interface Builder中设置)仍为nil,因此创建的对象始终为ClassC。此外,首先创建ClassA对象,然后在其init调用中创建一个具有不同内存地址的新ClassC对象,并且不释放ClassA个对象。我有三个问题:

1)原始ClassA对象会发生什么? (我认为它已泄露,但我想知道)。

2)如何避免泄漏?

3)我如何实现我真正想要的?在设置委托时(例如,在awakeFromNib方法中),重置对象为时已晚。

1 个答案:

答案 0 :(得分:3)

  1. 是的,我认为它会被泄露,因为它在alloc之后的保留计数为+1,但没有任何内容可以释放它。

  2. 在重新分配[self release]的值之前,您可以使用self。有些人认为应该直接[self dealloc],但我个人更喜欢前者。

  3. 我认为,从笔尖实例化的对象会发送initWithCoder:条消息,因此请改写而不是init。虽然在这一点上,我仍然不确定是否会设置delegate