Objective c 由于使用动态内容引发NSException而导致ARC内存泄漏

Objective c 由于使用动态内容引发NSException而导致ARC内存泄漏,objective-c,exception,automatic-ref-counting,Objective C,Exception,Automatic Ref Counting,使用ARC,以下示例都有内存泄漏,因为引发了具有动态内容的异常。没有发布动态内容并不奇怪,因为异常阻止了函数的正常返回。这些内存泄漏其实不是什么大问题,因为应该谨慎使用异常,例如当应用程序出现故障而无法恢复时。我只是想确保没有任何方法可以释放我目前不知道的记忆 以下两个示例使用上述方法throwsException抛出异常,以减少示例的人为性 注意使用@autoreleasepool,仍然存在内存泄漏 - (void)test_throwsException_wAutoreleasepoo

使用ARC,以下示例都有内存泄漏,因为引发了具有动态内容的异常。没有发布动态内容并不奇怪,因为异常阻止了函数的正常返回。这些内存泄漏其实不是什么大问题,因为应该谨慎使用异常,例如当应用程序出现故障而无法恢复时。我只是想确保没有任何方法可以释放我目前不知道的记忆



以下两个示例使用上述方法
throwsException
抛出异常,以减少示例的人为性


注意使用
@autoreleasepool
,仍然存在内存泄漏

- (void)test_throwsException_wAutoreleasepool
{
    @autoreleasepool {
        @try
        {
            [self throwsException];
            NSLog(@"No exception raised.");
        }
        @catch (NSException *exception)
        {
            NSLog(@"%@ - %@", [exception name], [exception reason]);
        }
    }
}

与上面的示例相同,只是通过在
try
块中直接引发异常更加巧妙

- (void)test_consolidated_raiseFormat
{
    @autoreleasepool {
        @try
        {
            NSString *dynamicContent = [NSString stringWithFormat:@"random value[%d]", arc4random() % 100];
            [NSException raise:@"Some random thing" format:@"%@", dynamicContent];
            NSLog(@"No exception raised.");
        }
        @catch (NSException *exception)
        {
            NSLog(@"%@ - %@", [exception name], [exception reason]);
        }
    }
}

本例使用了名为的异常。没有预期的差异

- (void)test_consolidated_exceptionWithName
{
    @autoreleasepool {
        @try
        {
            NSString *dynamicContent = [NSString stringWithFormat:@"random value[%d]", arc4random() % 100];
            NSException *exception = [NSException exceptionWithName:@"Some random thing"
                                                             reason:dynamicContent
                                                           userInfo:nil];
            [exception raise];
            NSLog(@"No exception raised.");
        }
        @catch (NSException *exception)
        {
            NSLog(@"%@ - %@", [exception name], [exception reason]);
        }
    }
}
- (void)test_consolidated_initWithName
{
    @autoreleasepool {
        @try
        {
            NSString *dynamicContent = [NSString stringWithFormat:@"random value[%d]", arc4random() % 100];
            NSException *exception = [[NSException alloc] initWithName:@"Some random thing"
                                                                reason:dynamicContent
                                                              userInfo:nil];
            [exception raise];
            NSLog(@"No exception raised.");
        }
        @catch (NSException *exception)
        {
            NSLog(@"%@ - %@", [exception name], [exception reason]);
        }
    }
}

本例使用
initWithName
。没有预期的差异

- (void)test_consolidated_exceptionWithName
{
    @autoreleasepool {
        @try
        {
            NSString *dynamicContent = [NSString stringWithFormat:@"random value[%d]", arc4random() % 100];
            NSException *exception = [NSException exceptionWithName:@"Some random thing"
                                                             reason:dynamicContent
                                                           userInfo:nil];
            [exception raise];
            NSLog(@"No exception raised.");
        }
        @catch (NSException *exception)
        {
            NSLog(@"%@ - %@", [exception name], [exception reason]);
        }
    }
}
- (void)test_consolidated_initWithName
{
    @autoreleasepool {
        @try
        {
            NSString *dynamicContent = [NSString stringWithFormat:@"random value[%d]", arc4random() % 100];
            NSException *exception = [[NSException alloc] initWithName:@"Some random thing"
                                                                reason:dynamicContent
                                                              userInfo:nil];
            [exception raise];
            NSLog(@"No exception raised.");
        }
        @catch (NSException *exception)
        {
            NSLog(@"%@ - %@", [exception name], [exception reason]);
        }
    }
}

似乎NSException从根本上与ARC不兼容。从Swift没有实施这些例外的事实来看,也是出于同样的原因。我想知道为什么您认为泄漏是通过将项附加到异常而不是在引发事件之前将保留计数设置为“1”触发的

想想看,NSException是一个对象,它的选择器可以动态传递,因此编译器将“raise”解释为语言特性事件是不对的。因此,在该特定位置未添加电弧释放说明

更新-这里是另一个解释