È possibile farlo funzionare, utilizzando diverse variabili backing, quando sintetizzando sembra che questo: @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;
}
uscita
2012-05-27 01:59:16.221 NicestArray[2312:403] __NSArrayI
2012-05-27 01:59:16.225 NicestArray[2312:403] __NSArrayM
Un altro approccio potrebbe essere quello di avere 2 metodi init nella classe base, uno, che istanzia la proprietà e uno, che non lo farà, ma lascia quell'attività per il bambino c lass: questo ti impedirà di creare oggetti costosi solo per buttarli via.
Ora la classe base può essere istanziata direttamente con il secondo init e passare a uno stato falso. È possibile evitare ciò controllando il tipo di classe autonoma con isMemberOfClass:
e generando un errore, se il tipo di classe è la classe base.
@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;
}
+1 per rispondere alla domanda e per dimostrarmi facilmente di sbagliare. :) –