我试图将 NSJSONSerialization 方法封装在 Category
上的 NSObject
中,而不是在整个代码中重复 [de]/序列化。
。H
#import <Foundation/Foundation.h>
@interface NSObject (AYIAdditions)
+ (NSString *)JSONString;
+ (id)objectFromJSONString;
+ (id)objectFromJSONData;
@end
但是,我收到错误:“NSMutableDictionary”没有可见的@interface 声明选择器“JSONString”
NSMutableDictionary
继承了 NSObject
,因此应该继承这些类别方法,对吗?我错过了什么?顺便说一句,使用类别是一种好方法( mentioned by Ray Wenderlich )。或者我应该简单地使用一些类方法创建一个自定义对象。
最佳答案
在代码中:
+ (NSString *)JSONString;
+
(加号)表示类方法。您很可能需要一个实例方法,如下所示:- (NSString *)JSONString;
关于如何实现序列化的方法论: 这是相当“旁白”。您所要求的范围非常广泛,而且您提供的细节很少。这实际上取决于您的需求范围以及您想投入多少时间/精力,但要权衡一下意见:
NSObject
上的一个类别对我来说似乎有点过于宽泛。我认为它不太可能产生比似乎更合乎逻辑的选择协议(protocol)更好的结果。坦率地说,我希望
NSJSONSerialization
已经声明了一个协议(protocol)来序列化我们自己的自定义模型对象,类似于 NSCoding
,但他们没有。这通常仍然是我将对象编码为 JSON
时所走的路线。协议(protocol)可能如下所示:NSString * const MySerializationClassKey = @"MySerializationClassKey";
@protocol MySerializationProtocol <NSObject>
@required
-(NSDictionary *)dictionarySerialization;
-(id)initFromDictionarySerialization:(NSDictionary *)dictionary;
@end
然后你的自定义模型对象可以像这样序列化和反序列化:(过于简单化)
@interface MyModel() <MySerializationProtocol>
@property (strong) NSString *name;
@end
@implementation MyModel
NSString * const MyModelNameKey = @"MyModelNameKey";
@synthesize name = _name;
-(NSDictionary *)dictionarySerialization{
// encode object as dictionary
return @{MySerializationClassKey: NSStringFromClass(self.class), MyModelNameKey: _name.copy};
}
-(id)initFromDictionarySerialization:(NSDictionary *)dictionary{
if ((self = [super init])){
_name = [dictionary objectForKey:MyModelNameKey];
}
return self;
}
@end
现在假设,为了不在答案中输入完整的序列化库,您只有这些模型对象的平面
NSArray
。您可以创建一个使用 NSJSONSerialization
与这些方法合作的类。为了使每次调用更容易,如下所示:@interface MySerializer : NSObject
@end
@implementation MySerializer
+(NSData *)jsonDataFromObject:(NSMutableArray *)array{
for (NSUInteger index = 0; index < array.count; index++) {
NSObject *object = [array objectAtIndex:index];
if ([object conformsToProtocol:@protocol(MySerializationProtocol)]){
NSDictionary *dictRep = [(id<MySerializationProtocol>)object dictionarySerialization];
[array replaceObjectAtIndex:index withObject:dictRep];
}
}
return [NSJSONSerialization dataWithJSONObject:array options:0 error:nil];
}
+(NSMutableArray *)objectFromJSONData:(NSData *)data{
NSMutableArray *array = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
for (NSUInteger index = 0; index < array.count; index++) {
NSObject *object = [array objectAtIndex:index];
if ([object isKindOfClass:[NSDictionary class]]){
NSDictionary *dict = (NSDictionary *)object;
NSString *className = [dict objectForKey:MySerializationClassKey];
if (className.length > 0) {
NSObject *deserialized = [[NSClassFromString(className) alloc] initFromDictionarySerialization:dict];
if (deserialized) [array replaceObjectAtIndex:index withObject:deserialized];
}
}
}
return array;
}
@end
现在显然要从这样的代码中获得任何里程,您必须递归遍历可能的数组和字典。但这是我的首选路线。
关于iOS类继承封装NSJSONSerialization,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15666273/