如何获取方法返回的所有元素包括从超类定义的元素?

时间:2015-07-16 21:17:38

标签: ios arrays inheritance

我正在写一个json<>模型序列化器。其中一个功能是在转换为json时忽略模型中的某些属性。我让模型实现一个- (NSArray *)ignoreProperties方法来告诉序列化器它应该忽略哪些属性。显然它需要支持继承。但现在我仍然坚持如何正确地组合对象本身和所有超类的所有数组元素。

@protocol SerializerMapping <NSObject>
- (NSArray *)ignoreProperties;
@end

@interface BaseModel : NSObject <SerializerMapping>
@property NSString *baseProperty;
@end

@implementation BaseModel
- (NSArray *)ignoreProperties {
    return nil; // nothing to ignore
}
@end

// ---
@interface SuperModel : BaseModel
@property NSString *property1;
@property NSString *property2;
@end

@implementation SuperModel
- (NSArray *)ignoreProperties {
    return @[@"property1"];
}
@end

// ---
@interface AwesomeModel : SuperModel
@property NSString *property3;
@property NSString *property4;
@end

@implementation AwesomeModel
- (NSArray *)ignoreProperties {
    return @[@"property3"];
}
@end

// --- serializer
AwesomeModel *obj = [AwesomeModel new];
NSArray *blackList = [obj ignoreProperties]; // only returns "property3"

显然上面的代码不起作用,但我如何实现ignoreProperties,以便它会返回property1property3

非常糟糕的方式:

@implementation AwesomeModel
- (NSArray *)ignoreProperties {
    return [[super ignoreProperties] arrayByAddingObjectsFromArray:@[@"property3"]];
}
@end

很多漏洞的可能性。如果一个子类忘记调用super链将被破坏。或BaseModel返回nil,然后代码根本不起作用。

1 个答案:

答案 0 :(得分:0)

我认为teamnorge在正确的轨道上他的代码不会像发布的那样工作,因为阵列不可变。

使您的属性成为可变数组。让基类用init init方法创建它:

在基类标题中:

@property (nonatomic, retain) NSMutableArray *ignoreProperties;

然后在你的基类的init中:

-(instanceType) init;
{
  self = [super init];
  if (!self)
    return nil;
  self.ignoreProperties =  [@[@"property1"] mutableCopy];
}

在您的子类的init中:

-(instanceType) init;
{
  self = [super init];
  if (!self)
    return nil;
  [self.ignoreProperties  addObject: @"property2"];
  //or to add multiple objects...
  NSArray *newProperties = @[@"property2", @"property3"];
  [self.ignoreProperties  addObjectsFromArray: newProperties];
}

为了提高效率,最好使数组不可变,并让子类的init方法将其替换为使用arrayByAddingObjectarrayByAddingObjectsFromArray创建的数组。 (不可变对象的系统成本低于它们的可变形式。在这种情况下,属性数组只会在类的初始化时创建一次,然后在其生命周期内持续存在。)