2011-07-04 21 views
5

我阻止了某些东西,我相信它太大了。 我有这个样子将自定义对象写入.plist中的可可

@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]; 

downloadArrayNSMutableArray。我的plist读取/写入没有问题,path位于应用程序支持中,当我登录时显示plist路径。

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

+0

为什么将downloadArray的retainCount设置为2?只需要\t downloadArray = [[NSMutableArray alloc] init]; –

回答

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]; 
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]; 

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

而且,在你分配你downloadArray对象的代码,您呼叫-alloc,然后在对象上-retain,这将具有2的retainCount你应该重新阅读的Objective-C Memory Management Guidelines离开它。

+0

值得吗?我的意思是,这比仅将属性转换为字典并保存为字典更高效?为什么我需要将我的对象包装到nsdata中,或者有关于此的一些建议? –

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"); 
} 
相关问题