【问题标题】:How to serialize a class in IOS sdk (Objective-c)?如何在IOS sdk(Objective-c)中序列化一个类?
【发布时间】:2012-02-13 20:31:08
【问题描述】:

如何在objective-c中序列化下面的类,以便与SBJson一起使用?

我在使用此代码时收到“Animal 不支持 JSON 序列化”错误。

谁能指出我哪里出错了?

Animal.h文件内容如下

#import <UIKit/UIKit.h>

@interface Animal : NSObject<NSCoding> {
    NSString *name;
    NSString *description;
    NSString *imageURL;
}

@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSString *description;
@property (nonatomic, retain) NSString *imageURL;

-(id)initWithName:(NSString *)n description:(NSString *)d url:(NSString *)u;

@end

Animal.m文件内容如下

#import "Animal.h"

@implementation Animal
@synthesize name, description, imageURL;

-(id)initWithName:(NSString *)n description:(NSString *)d url:(NSString *)u {
    self.name = n;
    self.description = d;
    self.imageURL = u;
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    if(self = [super initWithCoder:aDecoder])
    {
        name = [[aDecoder decodeObjectForKey:@"name"] retain];
        description = [[aDecoder decodeObjectForKey:@"description"] retain];
        imageURL = [[aDecoder decodeObjectForKey:@"imageURL"] retain];
    }
    return [self initWithName:name description:description url:imageURL];
}

- (void)encodeWithCoder:(NSCoder *)encoder
{
    [super encodeWithCoder:encoder];
    [encoder encodeObject:name forKey:@"name"];
    [encoder encodeObject:description forKey:@"description"];
    [encoder encodeObject:imageURL forKey:@"imageURL"];
}    

@end

【问题讨论】:

    标签: iphone objective-c json serialization sbjson


    【解决方案1】:

    使您的自定义类符合NSCoding 协议,然后对其进行序列化。

    欲了解更多信息,请访问Apple documentation

    另外,这个link 也会帮助你。 按照此链接中的建议,将您的自定义类存档到 NSData 并按照 Apple 文档中的规定对其进行序列化。

    编辑 使您的Animal.m 如下:

    #import "Animal.h"
    
    @implementation Animal
    @synthesize name, description, imageURL;
    
    -(id)initWithName:(NSString *)n description:(NSString *)d url:(NSString *)u {
        self = [super init];
        if( self )
        {
           self.name = n;
           self.description = d;
           self.imageURL = u;
        }
        return self;
    }
    
    - (id)initWithCoder:(NSCoder *)aDecoder
    {
        self = [super init];
        if( self )
        {
            self.name = [aDecoder decodeObjectForKey:@"name"];
            self.description = [aDecoder decodeObjectForKey:@"description"];
            self.imageURL = [aDecoder decodeObjectForKey:@"imageURL"];
        }
        return self;
    }
    
    - (void)encodeWithCoder:(NSCoder *)encoder
    {
        [encoder encodeObject:name forKey:@"name"];
        [encoder encodeObject:description forKey:@"description"];
        [encoder encodeObject:imageURL forKey:@"imageURL"];
    }    
    
    @end
    

    【讨论】:

    • 第二个链接是关键。您使用[NSKeyedArchiver archivedDataWithRootObject:(id)] 和[NSKeyedUnarchiver unarchiveObjectWithData:(NSData *)] 来序列化和反序列化对象。
    【解决方案2】:

    【讨论】:

    • 我添加了以下方法,如“在 Objective-c/iPhone 中使自定义类可序列化?”一文中所述,但我仍然收到错误消息“Animal 不支持 JSON 序列化” " - (id)initWithCoder:(NSCoder *)aDecoder; - (void)encodeWithCoder:(NSCoder *)encoder;
    • 你是否让类符合NSCoding协议?
    • 我是为 iPhone 应用程序编写代码的新手。你能看看我原始问题中的源代码并指出我哪里出错了吗?
    【解决方案3】:

    查看新引入的 NSJSONSerialization 类:

    NSJSONSerialization class

    【讨论】:

      【解决方案4】:

      如果对你有帮助,我想你可以看看这个:Make a Custom Class Serializable

      【讨论】:

      • 我已添加此链接中所述的以下方法,但我仍然收到错误消息为“Animal 不支持 JSON 序列化” - (id)initWithCoder:(NSCoder *)aDecoder; - (void)encodeWithCoder:(NSCoder *)encoder;
      • 我认为 nscoding 是一种协议,我们应该以这种方式在 中实现,但如果你不明白我的意思,那么请检查这个raywenderlich.com/1914/… 这是本教程的目的不同但是我认为你可以从这里学习 nscoding 的使用..
      • 我已使用源代码以及您共享的链接中建议的更改更新了原始问题。
      【解决方案5】:

      要真正回答您关于如何使用 SBJson 的问题:实现 proxyForJson 方法。除非您正在序列化 NSArray 或 NSDictionary,否则您必须重写此方法才能使序列化工作。

      通过查看 SBJson 源代码(在 SBJsonWriter.m 中)可以看到是这种情况:

      - (NSData*)dataWithObject:(id)object {    
      ...   
          if ([object isKindOfClass:[NSDictionary class]])
                      ok = [streamWriter writeObject:object];
      
                  else if ([object isKindOfClass:[NSArray class]])
                      ok = [streamWriter writeArray:object];
      
                  else if ([object respondsToSelector:@selector(proxyForJson)])
                      return [self dataWithObject:[object proxyForJson]];
                  else {
                      self.error = @"Not valid type for JSON";
                      return nil;
                  }
          ...
          }
      }
      

      像这样在Animal.m 中实现proxyForJson(未测试):

      - (NSDictionary*) proxyForJson
      {
      return [NSDictionary dictionaryWithObjectsAndKeys:self.name, @"name",
                                                        self.description, @"description",
                                                        self.imageURL, @"imageURL", 
                                                        nil];
      }
      

      【讨论】:

        【解决方案6】:

        这个开源项目JSONCoding 使用新的 sdk 类和 NSCoding 协议使整个过程非常简单。

        【讨论】:

          【解决方案7】:

          另见https://github.com/jsonmodel/jsonmodel

          用于 JSON 的神奇数据建模框架 - 允许快速创建 智能数据模型。您可以在 iOS、macOS、watchOS 和 tvOS 中使用它 应用程序。

          这也是 Objective-c Swagger 客户端选择的库。

          【讨论】:

            猜你喜欢
            • 2012-01-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-11-30
            • 1970-01-01
            相关资源
            最近更新 更多