【发布时间】:2013-05-26 13:17:19
【问题描述】:
使用 ARC,以下示例都会由于引发具有动态内容的异常而导致内存泄漏。动态内容没有发布也就不足为奇了,因为异常阻止了函数的正常返回。这些内存泄漏确实不是一个大问题,因为应该谨慎使用异常,例如当应用程序失败而没有恢复机会时。我只是想确保没有任何方法可以释放我目前不知道的内存。
- (void)throwsException
{
NSString *dynamicContent = [NSString stringWithFormat:@"random value[%d]", arc4random() % 100];
[NSException raise:@"Some random thing" format:@"%@", dynamicContent];
}
下面两个例子使用上面的方法throwsException抛出异常,让例子不那么做作。
- (void)test_throwsException_woAutoreleasepool
{
@try
{
[self throwsException];
NSLog(@"No exception raised.");
}
@catch (NSException *exception)
{
NSLog(@"%@ - %@", [exception name], [exception reason]);
}
}
注意@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]);
}
}
}
此示例使用exceptionWithName。没有预期的差异。
- (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]);
}
}
}
此示例使用initWithName。没有预期的差异。
- (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]);
}
}
}
【问题讨论】:
标签: objective-c exception automatic-ref-counting