2012-03-06 103 views
0

计数用尽当我运行从SenTest的STAssertThrowsSpecificNamed打了一个电话里这样的代码:保留后@throw

@throw [[NSException alloc] initWithName:NSInvalidArchiveOperationException 
            reason:@"---some reason----" 
           userInfo:nil]; 

我得到(与NSZombieEnabled=YES):

*** -[NSException reason]: message sent to deallocated instance 0x100a81d60 

唯一的例外是某种STAssertThrowsSpecificNamed之前释放已完成处理。

我可以通过更换上面这段代码的@throw行避免该错误:

NSException *exception = [NSException exceptionWithName:NSInvalidArchiveOperationException 
               reason:@"---some reason----" 
               userInfo:nil]; 
@throw exception; 

我得到完全有或没有ARC相同的行为。没有弧这个代码也避免了错误:

@throw [[[NSException alloc] initWithName:NSInvalidArchiveOperationException 
            reason:@"---some reason----" 
           userInfo:nil] retain]; 

这是一个错误在SenTest?或编译器中的错误?或者是我的第一个@throw只是不正确?

回答

1

我现在专门使用+[NSException raise:format:]都ARC和手动保留释放下。

2

@throw在使用它之后释放对象,因此如果要将其包含在与@throw相同的行中,请使用-retain。

@throw [[[[NSException alloc] initWithName:NSInvalidArchiveOperationException 
            reason:@"---some reason----" 
           userInfo:nil] retain] autorelease]; 

这应该可以做到。

编辑:要检查特定ARC-代码,使用:

if(__has_feature(objc_arc)) { 
    @throw [[[NSException alloc] initWithName:NSInvalidArchiveOperationException 
             reason:@"---some reason----" 
            userInfo:nil]; 
} else { 
    @throw [[[[NSException alloc] initWithName:NSInvalidArchiveOperationException 
             reason:@"---some reason----" 
            userInfo:nil] retain] autorelease]; 
} 
+0

你想解释为什么第二个例子有效吗? – JeremyP 2012-03-06 12:11:56

+0

并且是你在ARC下推荐的第二个例子,我不能使用'retain'? – paulmelnikow 2012-03-06 16:32:10

+0

这样做的原因是因为我看到@throw释放了您创建的NSExceptions,因此如果您将-retain/-autorelease NSException传递给它,它将保留并在必要时释放。当“将对象赋予另一个对象”时,保留计数应该以这种方式使用,并且使用-autorelease,它只是意味着“必要时释放,或者将其留给垃圾回收”。 – 2012-03-06 17:16:11

1

我用这种形式现在坚持,因为,这似乎工作,既有和没有ARC

id exc = [NSException exceptionWithName:NSInvalidArchiveOperationException 
           reason:@"---some reason----" 
           userInfo:nil]; 
@throw exc; 

每Galaxas0的回答,@throw旨在释放例外它处理后。这仍然让我感到奇怪,尤其是在ARC之下。

在非ARC项目,用这个(也每Galaxas0):

@throw [[[[NSException alloc] initWithName:NSInvalidArchiveOperationException 
            reason:@"---some reason----" 
            userInfo:nil] retain] autorelease]; 
+1

为什么你不用'+ raise:format:'在NSException中呢?我没有使用该模式的内存问题。 – 2012-03-08 19:38:42

+0

我认为这就是我正在寻找的。 – paulmelnikow 2012-03-08 20:58:29

+0

我并不完全确定,但这就是我相信*它的设计。苹果建议使用第一条语句。如果我的回答(或您的回答)有帮助,请将其标为正确答案! :] – 2012-03-08 23:30:42