首页 > 其他 > 详细

Objective-C NSData与实现NSCoding协议

时间:2015-11-30 12:53:48      阅读:365      评论:0      收藏:0      [点我收藏+]

NSData是Objective-C语言中数据的基本类型,其成分可以理解为字节指针和长度的封装的类,来看看源代码

@interface NSData : NSObject <NSCopying, NSMutableCopying, NSSecureCoding>

@property (readonly) NSUInteger length;
/*
 The -bytes method returns a pointer to a contiguous region of memory managed by the receiver.
 If the regions of memory represented by the receiver are already contiguous, it does so in O(1) time, otherwise it may take longer
 Using -enumerateByteRangesUsingBlock: will be efficient for both contiguous and discontiguous data.
 */
@property (readonly) const void *bytes NS_RETURNS_INNER_POINTER;

@end

 所谓数据之基本单位,就好比是和黄金作为等价物一样,人民币可以转黄金,美元也可以转黄金。NSData就是这样一般等价物的存在。

在网络传输、数据存储等地方,NSData是非常常用的。

任何对象转NSData,都需要遵循一个协议,就是NSCoding。

@protocol NSCoding

- (void)encodeWithCoder:(NSCoder *)aCoder;
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder; // NS_DESIGNATED_INITIALIZER

@end

 对于系统的Class,都是默认支持NSCoding协议的,但是如果你自定义了一个对象,比如手动去支持它,如下:

实现NSCoding协议:

(1)在.h文件里 

#import <Foundation/Foundation.h>

@interface ContactInfo : NSObject<NSCoding>

@property int userid;
@property (copy) NSString *username;
@property (copy) NSString *FriendlyName;
@property (copy) NSString *phoneNum;

@end

(2)在.m文件里的implementation添加实现NSCoding协议的方法:

//每个属性变量分别转码
-(void)encodeWithCoder:(NSCoder *)aCoder{
    [aCoder encodeObject:self.FYusername forKey:@"username"];
    [aCoder encodeObject:self.FriendlyName forKey:@"FriendlyName"];
    [aCoder encodeObject:self.phoneNum forKey:@"phoneNum"];

}

//分别把每个属性变量根据关键字进行逆转码,最后返回一个Student类的对象
-(id)initWithCoder:(NSCoder *)aDecoder{
    if (self = [super init]) {
        self.FYusername = [aDecoder decodeObjectForKey:@"username"];
        self.FriendlyName= [aDecoder decodeObjectForKey:@"FriendlyName"];
        self.phoneNum= [aDecoder decodeObjectForKey:@"phoneNum"];
    }
    return self;
}

这样就建立了任何对象和NSdata之间的桥梁。

可以通过归档函数来转成NSData:

    NSData *contactsData=[NSKeyedArchiver archivedDataWithRootObject:ContactsArray];

 

 

在项目实战中发现,实现NSCoding的类有2个好处:

1.可以对任何对象进行存储

2.可以对任何对象实现深拷贝

 

1.可以对任何对象进行存储

在iOS中,进行存储比较快捷的方式是NSUserDefaults,存储方式如下:

    [[NSUserDefaults standardUserDefaults] setObject:nickName forKey:UserDefault_NickName];
    [[NSUserDefaults standardUserDefaults] synchronize];

但它支持的数据类型很有限:

  NSNumber(NSInteger、float、double),NSString,NSData,NSArray,NSDictionary,BOOL.

      一般都是些不可变的基本类型,存储其他类型时,如NSMutableArray等类型时,会崩溃的。

那肿么办?

对的,先转NSData.

    NSData *contactsData=[NSKeyedArchiver archivedDataWithRootObject:ContactsArray];
    [[NSUserDefaults standardUserDefaults] setObject:contactsData forKey:UserDefault_ContactsArray];
    [[NSUserDefaults standardUserDefaults] synchronize];

当然,不能忽略的是,如果是自定义对象,别忘了给他造NSCoding的桥梁。

除了NSUserDefaults,另外存储NSData的方式可以用归档+地址:

    [NSKeyedArchiver archiveRootObject:obj toFile:path];

 

具体如何实现NSCoding协议,使用NSUserdefaults和NSKeyedArchiver进行存储,参考:

http://www.cnblogs.com/rayshen/p/4910749.html

 

2.实现深拷贝:

关于对象的拷贝,将在下一篇博客中阐述,这里简单说下使用NSKeyedArchiver来实现深拷贝:

难道拷贝对象这么麻烦吗?对的,要完全拷贝一个对象还真不是那么简单。

主要的方法是先将某个对象转NSData,然后NSData转回赋值给新建对象:

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:[DemoGlobalClass sharedInstance].ContactsArray];
NSMutableArray *contactsArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];

 

Objective-C NSData与实现NSCoding协议

原文:http://www.cnblogs.com/rayshen/p/5006619.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!