[英]How to use NSCoder
I am developing iphone application. 我正在开发iphone应用程序。
I use NSCoder. 我使用NSCoder。
MyApplication.h MyApplication.h
#define ITEMS_KEY @"items"
#define CATEGORIES_KEY @"categories"
#import <UIKit/UIKit.h>
@interface MyApplicationData : NSObject <NSCoding, NSCopying> {
NSMutableArray* items;
NSMutableArray* categories;
}
@property (nonatomic ,retain) NSMutableArray* items;
@property (nonatomic, retain) NSMutableArray* categories;
@end
Myapplication.m Myapplication.m
#import "MyApplicationData.h"
@implementation MyApplicationData
@synthesize items;
@synthesize categories;
#pragma mark NSCoding
- (void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:items forKey:ITEMS_KEY];
[aCoder encodeObject:categories forKey:CATEGORIES_KEY];
}
-(id)initWithCoder:(NSCoder *)aDecoder{
if(self = [super init]){
self.items = [aDecoder decodeObjectForKey:ITEMS_KEY];
self.categories = [aDecoder decodeObjectForKey:CATEGORIES_KEY];
}
return self;
}
#pragma mark -
#pragma mark NSCopying
-(id)copyWithZone:(NSZone *)zone{
MyApplicationData* copy = [[[self class]allocWithZone:zone]init];
items = [self.items copy];
categories = [self.categories copy];
return copy;
}
@end
But warnning. 但警告。
'NSCoder' may not respond to '-decodeDataObjectForKey'
How to use NSCoder? 如何使用NSCoder?
使用-decodeObjectForKey:
并阅读文档 。
Here is the NSCoding protocal methods from my LogEntry object, you can ignore the switch statement and the schema details though, those are from a base class I have written that allows me to keep sane track of changing data formats. 这是来自我的LogEntry对象的NSCoding协议方法,您可以忽略switch语句和架构详细信息,但这些来自我编写的基类,可以让我保持对更改数据格式的理解。
Please note that in addition to using decodeObjectForKey: you also need to make sure you retain/copy the given values as they are autoreleased when received. 请注意,除了使用decodeObjectForKey之外,您还需要确保保留/复制给定值,因为它们在收到时会自动释放。
- (id)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if (self != nil) {
switch ([schemaVersion intValue]) {
case 2:
filepath = [[coder decodeObjectForKey:@"filepath"] copy];
identifier = [coder decodeInt64ForKey:@"identifier"];
level = [coder decodeIntForKey:@"level"];
lineNumber = [[coder decodeObjectForKey:@"lineNumber"] retain];
message = [[coder decodeObjectForKey:@"message"] retain];
timestamp = [[coder decodeObjectForKey:@"timestamp"] retain];
break;
default:
[self release], self = nil;
break;
}
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:filepath forKey:@"filepath"];
[coder encodeInt64:identifier forKey:@"identifier"];
[coder encodeInt:level forKey:@"level"];
[coder encodeObject:lineNumber forKey:@"lineNumber"];
[coder encodeObject:message forKey:@"message"];
[coder encodeObject:timestamp forKey:@"timestamp"];
[super encodeWithCoder:coder];
}
我认为你应该使用-decodeObjectForKey:
I wrote a helper function for using NSCoding. 我编写了一个使用NSCoding的辅助函数。 It's a part of VSCore Library.
它是VSCore库的一部分。 Check it out here:
看看这里:
@interface QuickCoding : NSObject
+ (void)quickEncode:(NSObject<NSCoding>*)object withEncoder:(NSCoder*)encoder;
+ (void)quickDecode:(NSObject<NSCoding>*)object withDecoder:(NSCoder*)decoder;
@end
And the .m file: 和.m文件:
#import "QuickCoding.h"
#import "ReflectionHelper.h"
#define QUICK_CODING_HASH @"h4"
@implementation QuickCoding
+ (void)quickEncode:(NSObject<NSCoding>*)object withEncoder:(NSCoder *)encoder{
NSArray *codingKeys = [ReflectionHelper fieldsList:[object class]];
NSUInteger hash = [[codingKeys componentsJoinedByString:@""] hash];
[encoder encodeObject:@(hash) forKey:QUICK_CODING_HASH];
[codingKeys enumerateObjectsUsingBlock:^(NSString *key, __unused NSUInteger idx, __unused BOOL *stop) {
id val = [object valueForKey:key];
if ([val conformsToProtocol:@protocol(NSCoding)]){
[encoder encodeObject:val forKey:key];
}
}];
}
+ (void)quickDecode:(NSObject<NSCoding>*)object withDecoder:(NSCoder *)decoder{
NSArray *codingKeys = [ReflectionHelper fieldsList:[object class]];
NSUInteger hash = [[codingKeys componentsJoinedByString:@""] hash];
NSUInteger decodedHash = [[decoder decodeObjectForKey:QUICK_CODING_HASH] unsignedIntegerValue];
BOOL equalHash = hash == decodedHash;
[codingKeys enumerateObjectsUsingBlock:^(NSString *key, __unused NSUInteger idx, __unused BOOL *stop) {
id val = [decoder decodeObjectForKey:key];
if (equalHash || val){
[object setValue:val forKey:key];
}
}];
}
@end
Full code is here: https://github.com/voipswitch/VSCore/tree/master/VSCore/Storage 完整代码在这里: https : //github.com/voipswitch/VSCore/tree/master/VSCore/Storage
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.