在Cocoa中将自定义对象写入.plist [英] Write custom object to .plist in Cocoa

查看:161
本文介绍了在Cocoa中将自定义对象写入.plist的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我阻塞了一些东西,我相信它太大了。
我有一个自定义对象,看起来像这样

I am blocking into something and I am sure it is too big. I have a custom object that look like this

 @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)。现在当我尝试做这样的事情只是为了测试

As you can see it implement NSCoding (I think so, NSObject does not conform to NSCoding). Now when I try to do something like that just to test

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读/写很好,路径位于应用程序支持中,当我记录它显示plist路径。

downloadArray is a NSMutableArray. My plist read/write is fine, the path is located in the application support and when I log it show the plist path.

但它只是不把数组写到plist,任何想法?

But it just does not write the array to the plist, any idea ?

推荐答案

属性列表文件只能存储基本数据类型,不能包含自定义对象。如果你想将它写入plist,你需要将你的对象转换为一个 NSData 对象。你可以用 NSKeyedArchiver 来做到这一点,它将符合 NSCoding 协议的对象编码为 NSData object。

Property list files can only store basic data types and cannot contain custom objects. You need to convert your object to an NSData object if you want it to be written to the plist. You can do this with NSKeyedArchiver, which will encode an object which conforms to the NSCoding protocol into an NSData object.

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 object,你使用 NSKeyedUnarchiver

When you want to reconstruct your object from the NSData object, you use NSKeyedUnarchiver:

NSData* objData = [downloadArray objectAtIndex:0];
DownloadObject* object = [NSKeyedUnarchiver unarchiveObjectWithData:objData];

您的代码中还有一些内存泄漏。在您的 -initWithCoder:方法中,您不应该使用访问器设置ivars的值,您应该直接设置ivars,如下:

You also have several memory leaks in your code. In your -initWithCoder: method, you should not be using accessors to set the value of the ivars, you should just set the ivars directly, like so:

key = [[coder decodeObjectForKey:@"Key"] copy];

您正在呼叫 -retain 指定为 copy 的访问器,这意味着您的对象的保留计数为2,不会被释放。一般来说,你应该避免在init方法中使用访问器。

You are calling -retain and then using the accessor which is specified as copy, which will mean your object has a retain count of 2 and will not be released. In general you should avoid using accessors in init methods.

此外,在分配 downloadArray ,你在对象上调用 -alloc ,然后调用 -retain ,这将使它的retainCount为2。您应该重新阅读Objective-C 内存管理指南

Also, in the code where you allocate your downloadArray object, you are calling -alloc and then -retain on the object, which will leave it with a retainCount of 2. You should re-read the Objective-C Memory Management Guidelines.

这篇关于在Cocoa中将自定义对象写入.plist的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆