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
And the implementation
@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
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
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.
But it just does not write the array to the plist, any idea ?
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];
When you want to reconstruct your object from the NSData
object, you use NSKeyedUnarchiver
:
NSData* objData = [downloadArray objectAtIndex:0];
DownloadObject* object = [NSKeyedUnarchiver unarchiveObjectWithData:objData];
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];
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.
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.