As already noted, you cannot write [self release]; . In addition, awakeAfterUsingCoder: not an initializer - you cannot reassign self .
Would this leak be?
Yes. Proved in the program below.
Or do I just need to trust the NSCoder object to free the source object for me?
Not.
One way to avoid the leak exists below - I would not call it a โnew templateโ, namely the first approach that came to mind. It includes an explicit self release and in this case an explicit save result:
#import <Foundation/Foundation.h> @interface MONBoolean : NSObject < NSCoding > - (id)initWithBool:(bool)pBool; - (bool)isTrue; - (bool)isFalse; @end static NSString * const MONBoolean_KEY_value = @"MONBoolean_KEY_value"; @implementation MONBoolean { bool value; } - (id)initWithBool:(bool)pBool { self = [super init]; if (0 != self) { value = pBool; } return self; } - (bool)isTrue { return true == value; } - (bool)isFalse { return false == value; } - (NSString *)description { return [[NSString alloc] initWithFormat:@"<%s:%p> : %s", object_getClassName(self), self, self.isTrue ? "true" : "false"]; } - (void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeBool:value forKey:MONBoolean_KEY_value]; } - (id)initWithCoder:(NSCoder *)aDecoder { self = [super init]; if (0 != self) { value = [aDecoder decodeBoolForKey:MONBoolean_KEY_value]; } return self; } - (id)awakeAfterUsingCoder:(NSCoder *)aDecoder { const bool b = value; // cannot reassign self outside of an initializer. // if not released, will result in a leak: CFRelease((__bridge const void*)self); MONBoolean * result = [[MONBoolean alloc] initWithBool:b]; // now we have to retain explicitly because this is // an autoreleasing method: CFRetain((__bridge const void*)result); return result; } @end int main(int argc, const char * argv[]) { @autoreleasepool { MONBoolean * a = [[MONBoolean alloc] initWithBool:true]; NSData * data = [NSKeyedArchiver archivedDataWithRootObject:a]; MONBoolean * b = [NSKeyedUnarchiver unarchiveObjectWithData:data]; NSLog(@"%@", b); } system("leaks NAME_OF_PROCESS_HERE"); return 0; }
justin
source share