保留@throw后用尽的计数

时间:2012-03-06 04:23:22

标签: objective-c xcode cocoa sentestingkit

当我在SenTest的STAssertThrowsSpecificNamed

调用中运行此代码时
@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,我都会得到完全相同的行为。如果没有ARC,此代码也可以避免错误:

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

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

3 个答案:

答案 0 :(得分: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];
}

答案 1 :(得分: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];

答案 2 :(得分:1)

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