gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 05:00:24 25 4
gpt4 key购买 nike

使用 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 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]);
}
}
}

此示例使用 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]);
}
}
}

最佳答案

看起来 NSException 从根本上与 ARC 不兼容。出于同样的原因,从这些异常没有在 Swift 中实现这一事实来判断。我很想知道为什么您认为泄漏是通过将项目附加到异常来触发的,而不是在引发事件之前简单地将保留计数设置为“1”。

想一想——NSException 是一个对象,它的选择器可以动态传递,所以编译器将“引发”解释为语言特性事件是不正确的。因此,没有在该特定位置添加 ARC 发布说明。

更新 - 这是另一种解释

Why does "try catch" in Objective-C cause memory leak?

关于objective-c - 由于使用动态内容引发 NSException 而导致 ARC 内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16845065/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com