Iphone 如何使用NSCoder
我正在开发iphone应用程序 我使用NSCoder MyApplication.hIphone 如何使用NSCoder,iphone,objective-c,cocoa,Iphone,Objective C,Cocoa,我正在开发iphone应用程序 我使用NSCoder MyApplication.h #define ITEMS_KEY @"items" #define CATEGORIES_KEY @"categories" #import <UIKit/UIKit.h> @interface MyApplicationData : NSObject <NSCoding, NSCopying> { NSMutableArray* items; NSMutabl
#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
但是警告
'NSCoder' may not respond to '-decodeDataObjectForKey'
如何使用NSCoder?我认为您应该使用
-decodeObjectForKey:
使用-decodeObjectForKey:
和。以下是我的LogEntry对象的NSCoding协议方法,您可以忽略switch语句和模式细节,这些都来自我编写的一个基类,它允许我对不断变化的数据格式保持理智的跟踪
请注意,除了使用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];
}
我为使用NSCoding编写了一个helper函数。它是VSCore库的一部分。在这里查看:
@interface QuickCoding : NSObject
+ (void)quickEncode:(NSObject<NSCoding>*)object withEncoder:(NSCoder*)encoder;
+ (void)quickDecode:(NSObject<NSCoding>*)object withDecoder:(NSCoder*)decoder;
@end
@接口快速编码:NSObject
+(void)quickEncode:(NSObject*)对象带编码器:(NSCoder*)编码器;
+(void)快速解码:(NSObject*)对象与解码器:(NSCoder*)解码器;
@结束
和.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
#导入“QuickCoding.h”
#导入“ReflectionHelper.h”
#定义快速编码散列@“h4”
@快速编码的实现
+(void)quickEncode:(NSObject*)对象带编码器:(NSCoder*)编码器{
NSArray*codingKeys=[ReflectionHelper fieldsList:[对象类]];
NSInteger哈希=[[codingKeys componentsJoinedByString:@”“]哈希];
[编码器编码对象:@(哈希)forKey:QUICK_CODING_hash];
[codingKeys enumerateObjectsUsingBlock:^(NSString*键,_未使用的整数idx,_未使用的布尔*停止){
id val=[object valueForKey:key];
如果([val-conformsToProtocol:@协议(NSCoding)]){
[编码器编码对象:val-forKey:key];
}
}];
}
+(void)快速解码:(NSObject*)带解码器的对象:(NSCoder*)解码器{
NSArray*codingKeys=[ReflectionHelper fieldsList:[对象类]];
NSInteger哈希=[[codingKeys componentsJoinedByString:@”“]哈希];
NSUInteger decodedHash=[[decoder decodeObjectForKey:QUICK_CODING_HASH]unsignedInteger值];
BOOL equalHash=hash==decodedHash;
[codingKeys enumerateObjectsUsingBlock:^(NSString*键,_未使用的整数idx,_未使用的布尔*停止){
id val=[decoder-decodeObjectForKey:key];
if(equalHash | | val){
[对象设置值:val-forKey:key];
}
}];
}
@结束
完整代码如下:需要提醒保留或复制这些对象的任何人也需要一个指向内存管理规则的链接:添加了正在制作的源代码。这里面有问题吗?我在您发布的代码中看到的最大问题是您没有保留从编码器检索到的值。
#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