创建不同的子类的子类物业(Create subclass with different subcla

2019-06-24 20:24发布

说我有这个类

@interface CustomClass : NSObject

@property (nonatomic, strong) NSArray * nicestArrayEver;

@end

我想创建CustomClass的子类,但这里是渔获

@interface ASubClassCustomClass : CustomClass

@property (nonatomic, strong) NSMutableArray * nicestArrayEver;

@end

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

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

Answer 1:

你可以把它的工作,通过使用不同的后盾变量,当合成它看起来像这样: @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;
}

产量

2012-05-27 01:59:16.221 NicestArray[2312:403] __NSArrayI
2012-05-27 01:59:16.225 NicestArray[2312:403] __NSArrayM

另一种方法可能是在基类,一个2种初始化方法,将实例属性和一个,那不会,但保留对儿童类的任务 - 这将阻止您创建昂贵的对象只是为了把它们远。
现在的基类可以直接与第二初始化实例化和去假状态。 您可以通过检查自类的类型与避免这种isMemberOfClass:并抛出一个错误,如果类类型的基类。

@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;
}


Answer 2:

我不明白为什么你会想这样做,但我会建议你做如下:在子类中声明一个单独的NSMutableArray属性(姑且称之为nicestMutableArrayEver)和覆盖吸你的超NSArray的属性返回在mutableArray实例:

- (NSArray *)nicestArrayEver {
    return [self nicestMutableArrayEver];
}

通过这种方式,你可以只要你引用父财产取回您的mutableArray。

最好,



Answer 3:

性能几乎从未应该有可变类型。 如果他们这样做,那么调用者可以得到指针和变异及其背后的对象的属性。 如果属性应该是外部可变的,这应该是通过突变方法。

请记住,属性定义接口,而不是实现。 @synthesize可以创建一个从财产申报执行,但如果会做错误的事情,你不应该使用它。

所以,第一步是定义你的类和子类的接口,而无需执行方面。 只有当你知道这个接口应该是你应该设计每个执行什么。

是否一个属性是从外部可变的,所述背衬的实例变量可能需要是可变的。 类可能需要纯粹的内部变异自有物业。

你可以做的基类有一个指定初始化这需要数组对象作为参数(类型的id ,这样子类的覆盖不必强制转换为把它当作一个NSMutableArray* )。 然后,在类的“正常”的初始化会调用与指定初始化NSArray使用。 子类的指定初始化会调用父类的指定初始化,在路过NSMutableArray使用。

可替换地,基类初始(一个或多个)可以调用出另一种方法,以获得阵列。 基类的实现将返回一个NSArray 。 子类可以覆盖该方法返回一个NSMutableArray



Answer 4:

你不能真正做到这一点。 只要创建CustomClassNSMutableArray 。 你可以创建这些类型id和检查isKindOfClass:但是这只是一个苦差事,而不是真的有必要。

其实只有两个原因,我可以看到做什么你问:

  1. 要避免的额外开销NSMutableArray
  2. 为了防止CustomClass修改该数组的内容,除非它是一个ASubClassCustomClass

虽然这些都是很好的目标,我会说,在这种情况下,它是值得的,简化一点。



文章来源: Create subclass with different subclass property