Bạn có thể làm cho nó hoạt động, bằng cách sử dụng các biến sự ủng hộ khác nhau, khi tổng hợp nó trông như thế này: @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;
}
đầu ra
2012-05-27 01:59:16.221 NicestArray[2312:403] __NSArrayI
2012-05-27 01:59:16.225 NicestArray[2312:403] __NSArrayM
cách tiếp cận khác có thể là để có 2 phương thức init trong lớp cơ sở, một phương thức sẽ khởi tạo thuộc tính và một, điều đó sẽ không, nhưng để lại nhiệm vụ đó cho con c lass - điều này sẽ ngăn cản bạn tạo ra các vật đắt tiền chỉ để vứt chúng đi.
Bây giờ lớp cơ sở có thể được khởi tạo trực tiếp với init thứ hai và đi đến trạng thái sai. Bạn có thể tránh điều này bằng cách kiểm tra loại tự lớp với isMemberOfClass:
và ném một lỗi, nếu loại lớp là lớp cơ sở.
@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 để trả lời câu hỏi và để chứng minh cho tôi sai. :) –