我试图将 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/

10-12 19:08