实现NSCoding
NSCoding 是一个protocol,里头只有两个method 要实现
@protocol NSCoding
- (void)encodeWithCoder:(NSCoder *)aCoder;
- (id)initWithCoder:(NSCoder *)aDecoder;
@end
encodeWithCoder:
的用途是将我们的实例透过NSCoder转成NSData,至于initWithCoder:
刚好相反,就是透过NSCoder,再把NSData转回实例。
假如我们现在有一个叫做KKSongTrack 的class,用来代表KKBOX 里头的一首歌,里头只有songName、albumName 与artistName 三个property,这三个property 都是NSString。
@interface KKSongTrack : NSObject <NSCoding>
@property (strong, nonatomic) NSString *songName;
@property (strong, nonatomic) NSString *albumName;
@property (strong, nonatomic) NSString *artistName;
@end
在实现的时候,我们就可以用NSCoder的相关method对资料做encode与decode。由于我们的property都是NSString,都是Objective-C实例,所以我们选择encodeObject:forKey:
以及decodeObjectForKey:
。实现如下:
#import "KKSongTrack.h"
static NSString *const kSongNameKey = @"song_name";
static NSString *const kAlbumNameKey = @"album_name";
static NSString *const kArtistNameKey = @"artist_name";
@implementation KKSongTrack
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@ %p %@ - %@ - %@>",
NSStringFromClass([self class]), self,
self.songName, self.albumName, self.artistName];
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super init];
if (self) {
self.songName = [coder decodeObjectForKey:kSongNameKey];
self.albumName = [coder decodeObjectForKey:kAlbumNameKey];
self.artistName = [coder decodeObjectForKey:kArtistNameKey];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.songName forKey:kSongNameKey];
[aCoder encodeObject:self.albumName forKey:kAlbumNameKey];
[aCoder encodeObject:self.artistName forKey:kArtistNameKey];
}
除了Objective-C 实例类型外,NSCoder 还有处理BOOL、整数以及浮点数相关的method 可以使用。
接下来如果我们想把歌曲转成NSData:
KKSongTrack *song = [[KKSongTrack alloc] init];
song.songName = @"orz 之歌";
song.albumName = @"orz 專輯";
song.artistName = @"orz";
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:song];
把NSData 再转回KKSongTrack:
KKSongTrack *decodeSong = [NSKeyedUnarchiver unarchiveObjectWithData:data];