我阻止某事,我确信它太大了。 我有一个看起来像这样的自定义对象
@interface DownloadObject : NSObject <NSCoding>{
NSNumber *key;
NSString *name;
NSNumber *progress;
NSNumber *progressBytes;
NSNumber *size;
NSString *path;
}
@property (copy) NSNumber *key;
@property (copy) NSString *name;
@property (copy) NSNumber *progress;
@property (copy) NSNumber *size;
@property (copy) NSString *path;
@property (copy) NSNumber *progressBytes;
-(id)initWithKey:(NSNumber *)k name:(NSString *)n progress:(NSNumber *)pro size:(NSNumber *)s path:(NSString *)p progressBytes:(NSNumber *)pb;
@end
实施
@implementation DownloadObject
@synthesize size, progress, name, key, path, progressBytes;
-(id)initWithKey:(NSNumber *)k name:(NSString *)n progress:(NSNumber *)pro size:(NSNumber *)s path:(NSString *)p progressBytes:(NSNumber *)pb
{
self.key = k;
self.name = n;
self.progress = pro;
self.size = s;
self.path = p;
self.progressBytes = pb;
return self;
}
-(id) initWithCoder: (NSCoder*) coder {
if (self = [super init]) {
self.key = [[coder decodeObjectForKey:@"Key"] retain];
self.name = [[coder decodeObjectForKey:@"Name"] retain];
self.progress = [[coder decodeObjectForKey:@"Progress"] retain];
self.size = [[coder decodeObjectForKey:@"Size"] retain];
self.path = [[coder decodeObjectForKey:@"Path"] retain];
self.progressBytes = [[coder decodeObjectForKey:@"ProgressBytes"]retain];
}
return self;
}
-(void) encodeWithCoder: (NSCoder*) coder {
[coder encodeObject:self.key forKey:@"Key"];
[coder encodeObject:self.name forKey:@"Name"];
[coder encodeObject:self.progress forKey:@"Progress"];
[coder encodeObject:self.size forKey:@"Size"];
[coder encodeObject:self.path forKey:@"Path"];
[coder encodeObject:self.progressBytes forKey:@"ProgressBytes"];
}
-(void)dealloc
{
[key release];
[name release];
[size release];
[progress release];
[path release];
[progressBytes release];
[super dealloc];
}
@end
正如你所看到它实现了NSCoding(我认为是这样,NSObject不符合NSCoding)。现在,当我尝试做这样的事情只是为了测试
downloadArray = [[[NSMutableArray alloc]init]retain];
NSNumber *number = [NSNumber numberWithInt:10];
DownloadObject *object = [[DownloadObject alloc]initWithKey:number name:@"hey" progress:number size:number path:@"hey" progressBytes:number];
[downloadArray addObject:object];
[object release];
[downloadArray writeToFile:path atomically:YES];
downloadArray
是NSMutableArray
。我的plist读/写很好,path
位于应用程序支持中,当我记录它时显示plist路径。
但它只是没有将数组写入plist,任何想法?
答案 0 :(得分:21)
属性列表文件只能存储基本数据类型,不能包含自定义对象。如果要将对象写入plist,则需要将对象转换为NSData
对象。您可以使用NSKeyedArchiver
执行此操作,NSCoding
会将符合NSData
协议的对象编码为DownloadObject *object = [[DownloadObject alloc]initWithKey:number name:@"hey" progress:number size:number path:@"hey" progressBytes:number];
NSData* objData = [NSKeyedArchiver archivedDataWithRootObject:object];
[downloadArray addObject:objData];
[object release];
对象。
NSData
如果要从NSKeyedUnarchiver
对象重建对象,请使用NSData* objData = [downloadArray objectAtIndex:0];
DownloadObject* object = [NSKeyedUnarchiver unarchiveObjectWithData:objData];
:
-initWithCoder:
您的代码中也有几处内存泄漏。在key = [[coder decodeObjectForKey:@"Key"] copy];
方法中,您不应该使用访问器来设置ivars的值,您应该直接设置ivars,如下所示:
-retain
您正在调用copy
,然后使用指定为downloadArray
的访问者,这意味着您的对象的保留计数为2且不会被释放。通常,您应该避免在init方法中使用访问器。
此外,在您分配-alloc
对象的代码中,您在对象上调用-retain
然后调用{{1}},这将使retainCount为2。您应该重新阅读Objective-C Memory Management Guidelines。
答案 1 :(得分:0)
这对我有用:
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:highScoreArray forKey:kHighScoreArrayKey];
[archiver finishEncoding];
[data writeToFile:[self dataFilePath] atomically:YES];
[data release];
[archiver release];
答案 2 :(得分:0)
BOOL flag = false;
ObjectFileClass *obj = [yourMutableArray objectAtIndex:0];
//TO Write Data . . .
NSData* archiveData = [NSKeyedArchiver archivedDataWithRootObject:obj.title];
flag =[archiveData writeToFile:path options:NSDataWritingAtomic error:&error];
}
if (flag) {
NSLog(@"Written");
//To Read Data . . .
NSData *archiveData = [NSData dataWithContentsOfFile:path];
id yourClassInstance = [NSKeyedUnarchiver unarchiveObjectWithData:archiveData]; // choose the type of your class instance . . .
NSLog(@"%@",yourClassInstance);
}else{
NSLog(@"Not Written");
}