I am jumping into a codebase that I'm unfamiliar with to resolve a critical crash, so I'm interested in finding a quick fix for the problem below that I can patch and come back to refactor later.
There is a strong coupling between the JSON structure returned by the web service and the Objective-C domain objects. The problem is that the JSON has a key description
which is already declared as part of the NSObject
protocol.
JSON:
{
"channel" : {
"description" : "blah",
"mount" : "blah",
"status" : "blah"
}
}
Objective-C:
@interface ABCChannel : NSObject
@property (nonatomic , strong) NSString *description;
@property (nonatomic , strong) NSString *mount;
@property (nonatomic , strong) NSString *status;
@end
Not surprising, the parsing code uses KVC to shuttle values from JSON to ObjC instances. From what I can tell, for Swift interop Apple has changed the internals of NSObject
's description
from a method to a readonly
property. Clang emits this:
warning: auto property synthesis will not synthesize property 'description' because it is 'readwrite' but it will be synthesized 'readonly' via another property [-Wobjc-property-synthesis]
Okay. So ,I see two options:
(Preferred) Change the name of the property from description
to something else. The problem is the parser will throw an exception in setValue:forKey:
because of the undefined description
key.
Back the description
property with an instance variable using @synthesize description = _channelDescription;
I see option #1 as taking a step in the direction of the inevitable future refactor, and I would like to set myself up for that, if possible. I can fix the KVC problem with ABCChannel
class no longer being compliant for the description
key with the following code:
- (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];
}
}
I am wondering if this is a terrible idea that will cause problems, and if I should just back the description
property with an ivar and completely address the refactor later.
Backing the description
property with an instance variable was the safest bet, especially for consistency across iOS 7 and iOS 8.