objective-c – 使用自动引用计数释放self的新模式是什么?

使用NSObject方法 – (id)awakeAfterUsingCoder:(NSCoder *)解码器作为示例,文档说:

Allows an object,after being decoded,to substitute another object
for itself. For example,an object that represents a font might,upon
being decoded,release itself and return an existing object having the
same font description as itself. In this way,redundant objects can be
eliminated.

通常你会这样做

[self release];
return substitutedobject;

使用ARC,你必须离开这条线.这不会泄漏吗?或者我应该只相信NSCoder对象为我发布原始对象?如果是这样,为什么你必须首先用非ARC代码明确释放自己?

根据编译器文档中关于self的内容,我认为self = nil是不正确的:http://clang.llvm.org/docs/AutomaticReferenceCounting.html#misc.self

解决方法

如上所述,你不能写[self release];.另外,awakeAfterUsingCoder:不是初始化者 – 你可能不会重新分配自己.

Wouldn’t this leak?

是.在下面的程序中证明.

Or should I just trust the NSCoder object to release the original object for me?

没有.

下面是一种避免泄漏的方法 – 我不会称之为“新模式”,这只是我想到的第一种方法.它涉及自我的显式释放,在这种情况下显式保留结果:

#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;
}

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...