创建具有不同子类属性的子类

Die*_*res 7 cocoa subclass objective-c

说我有这个班级

@interface CustomClass : NSObject

@property (nonatomic, strong) NSArray * nicestArrayEver;

@end
Run Code Online (Sandbox Code Playgroud)

我想创建一个CustomClass的子类,但这里是catch

@interface ASubClassCustomClass : CustomClass

@property (nonatomic, strong) NSMutableArray * nicestArrayEver;

@end
Run Code Online (Sandbox Code Playgroud)

你可以想象的问题是,当我初始化ASubClassCustomClass并调用它的超级初始化器(因为还需要其他属性)时,会创建不可变的nicestArrayEver ..我怎样才能避免它的创建,所以我可以设置可变的?

注意:这只是一个例子,真正的实现调用了很重要的创建和真正定制的子类(不是NSArray).

Vik*_*ica 5

您可以通过使用不同的后备变量使其工作,在合成它时如下所示: @synthesize nicestArrayEver = nicestArrayEverSubClass_;

#import <Foundation/Foundation.h>

@interface CustomClass : NSObject

@property (nonatomic, strong) NSArray * nicestArrayEver;

@end

@implementation CustomClass
@synthesize nicestArrayEver ;

-(id)init
{
    if (self = [super init]) {
        nicestArrayEver = [[NSArray alloc] init];
    }
    return self;
}
@end

@interface ASubClassCustomClass : CustomClass

@property (nonatomic, strong) NSMutableArray * nicestArrayEver;

@end

@implementation ASubClassCustomClass
@synthesize nicestArrayEver = nicestArrayEverSubClass_;

-(id)init{
    if (self = [super init]) {
        nicestArrayEverSubClass_ = [[NSMutableArray alloc] init];
    }
    return self;
}
@end



int main(int argc, const char * argv[])
{

    @autoreleasepool {

        CustomClass *c1 = [[[CustomClass alloc] init] autorelease];
        ASubClassCustomClass *c2 = [[[ASubClassCustomClass alloc] init] autorelease];

        NSLog(@"%@", NSStringFromClass([[c1 nicestArrayEver] class]));
        NSLog(@"%@", NSStringFromClass([[c2 nicestArrayEver] class]));

    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

产量

2012-05-27 01:59:16.221 NicestArray[2312:403] __NSArrayI
2012-05-27 01:59:16.225 NicestArray[2312:403] __NSArrayM
Run Code Online (Sandbox Code Playgroud)

另一种方法可能是在基类中有两个init方法,一个用于实例化属性,一个用于实例化属性,另一个用于子类的任务 - 这将阻止你创建昂贵的对象只是为了抛出它们远.
现在,基类可以直接使用第二个init进行实例化,并进入false状态.isMemberOfClass:如果类类型是基类,则可以通过检查self类类型来避免这种情况,并抛出错误.

@interface CustomClass : NSObject

@property (nonatomic, strong) NSArray * nicestArrayEver;
-(id)initWithoutArray;
@end

@implementation CustomClass
@synthesize nicestArrayEver ;

-(id) initWithoutArray
{
    if (self = [super init]) {
        if ([self isMemberOfClass:[CustomClass class]]) {
            [NSException raise:@"AbstractMethodCall" format:@"%@ should be called only from Subclasses of %@", NSStringFromSelector(_cmd), NSStringFromClass([self class])];
        }
    }
    return self;
}


-(id)init
{
    if (self = [super init]) {
        nicestArrayEver = [[NSArray alloc] init];
    }
    return self;
}
@end

@interface ASubClassCustomClass : CustomClass

@property (nonatomic, strong) NSMutableArray * nicestArrayEver;

@end

@implementation ASubClassCustomClass
@synthesize nicestArrayEver = nicestArrayEverSubClass_;

-(id)init{
    if (self = [super initWithoutArray]) {
        nicestArrayEverSubClass_ = [[NSMutableArray alloc] init];
    }
    return self;
}

@end



int main(int argc, const char * argv[])
{

    @autoreleasepool {

        CustomClass *c1 = [[[CustomClass alloc] init] autorelease];
        ASubClassCustomClass *c2 = [[[ASubClassCustomClass alloc] init] autorelease];

        NSLog(@"%@", NSStringFromClass([[c1 nicestArrayEver] class]));
        NSLog(@"%@", NSStringFromClass([[c2 nicestArrayEver] class]));

        //this works, as it is the subclass
        ASubClassCustomClass *shouldWork = [[[ASubClassCustomClass alloc] init] autorelease];

        // ouch!
        CustomClass *shouldCrash = [[[CustomClass alloc] initWithoutArray] autorelease];

    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)