Using ARC, the following examples all have memory leaks as the result of an exception being raised that have dynamic content. It is no surprise that the dynamic content has not been released because the exception prevents the normal return of the function. These memory leaks are really not a big issue, since exceptions should be used sparingly such as when an application fails without chance of recovery. I just want to make sure there there is not some way to release the memory that I am currently unaware of.
- (void)throwsException
{
NSString *dynamicContent = [NSString stringWithFormat:@"random value[%d]", arc4random() % 100];
[NSException raise:@"Some random thing" format:@"%@", dynamicContent];
}
The following two examples us the above method throwsException
to throw the exception to make the example less contrived.
- (void)test_throwsException_woAutoreleasepool
{
@try
{
[self throwsException];
NSLog(@"No exception raised.");
}
@catch (NSException *exception)
{
NSLog(@"%@ - %@", [exception name], [exception reason]);
}
}
Note the use of @autoreleasepool
, still has memory leaks.
- (void)test_throwsException_wAutoreleasepool
{
@autoreleasepool {
@try
{
[self throwsException];
NSLog(@"No exception raised.");
}
@catch (NSException *exception)
{
NSLog(@"%@ - %@", [exception name], [exception reason]);
}
}
}
Same as the above example, just more contrived by raising the exception directly in the try
block.
- (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]);
}
}
}
This example uses exceptionWithName
. No expected differences.
- (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]);
}
}
}
This example uses initWithName
. No expected differences.
- (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]);
}
}
}