“描述”属性的关键值编码 - 这完全是白痴吗?

时间:2014-11-09 15:42:53

标签: objective-c kvc

我跳进了一个我不熟悉的代码库来解决一个严重的崩溃问题,所以我有兴趣找到一个快速解决问题的方法,我可以修补并稍后重新进行重构。

Web服务返回的JSON结构与Objective-C域对象之间存在强大的耦合。问题是JSON有一个密钥description,它已经被声明为NSObject协议的一部分。

JSON:

{
    "channel" : {
        "description" : "blah",
        "mount"       : "blah",
        "status"      : "blah"
    }
}

目标-C:

@interface ABCChannel : NSObject

@property (nonatomic , strong) NSString *description;
@property (nonatomic , strong) NSString *mount;
@property (nonatomic , strong) NSString *status;

@end

不足为奇,解析代码使用KVC将值从JSON传递到ObjC实例。据我所知,对于Swift互操作,Apple已将NSObject description的内部从方法更改为readonly属性。 Clang发出这个:

  

警告:自动属性合成不会合成属性'说明'因为它是'readwrite'但它将被合成' readonly'通过另一个属性[-Wobjc-property-synthesis]

好。所以,我看到两个选择:

  1. (首选)将属性名称从description更改为其他名称。问题是由于未定义的setValue:forKey:密钥,解析器将在description中抛出异常。

  2. 使用description

  3. 使用实例变量返回@synthesize description = _channelDescription;属性

    我认为选项#1朝着不可避免的未来重构的方向迈出了一步,如果可能的话,我想为此做好准备。我可以使用以下代码解决ABCChannel类不再符合description密钥的KVC问题:

    - (id)valueForUndefinedKey:(NSString *)key
    {
        if ([key isEqualToString:@"description"]) {
            return [self valueForKey:@"details"];
        }
    
        return [super valueForUndefinedKey:key];
    }
    
    - (void)setValue:(id)value forUndefinedKey:(NSString *)key
    {
        if ([key isEqualToString:@"description"]) {
            [self setValue:value forKey:@"details"];
        }
        else {
            [super setValue:value forUndefinedKey:key];
        }
    }
    

    我想知道这是一个会导致问题的可怕想法,如果我应该用ivar支持description属性并稍后完全解决重构问题。

2 个答案:

答案 0 :(得分:1)

您可以通过一个函数从JSON解析器传递字典,该函数返回字典的副本,其中包含" description"作为一个关键普遍改变为理智的东西。然后在代码中重命名该属性。

也可能很快改变这种方式

答案 1 :(得分:0)

使用实例变量支持description属性是最安全的选择,特别是对于iOS 7和iOS 8的一致性。