gpt4 book ai didi

objective-c - 在 block 崩溃中分配 NSError 的调用方法

转载 作者:搜寻专家 更新时间:2023-10-30 19:56:00 28 4
gpt4 key购买 nike

我想了解为什么这会因 EXC_BAD_ACCESS 错误而崩溃。它从方法调用返回正常,但随后立即在 [self runMethodThatAssignsError:&error] 上崩溃。

我已经 found a similar post here ,但它没有解释发生了什么,而且相当陈旧。

- (void)checkError {
NSError *error;
[self runMethodThatAssignsError:&error]; // crashes after returning
NSLog(@"success");
}

- (BOOL)runMethodThatAssignsError:(NSError **)error {
[@[@1] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
*error = [NSError errorWithDomain:@"1" code:7 userInfo:@{}];
}];
return NO;
}

最佳答案

在 Instruments 中运行您的示例代码,看来 -[NSArray enumerateObjectsUsingBlock:] 正在将其 block 包装在自动释放池中。由于 NSError ** 指针在默认情况下被隐式假定为 __autoreleasing,因此您的 NSError 对象在分配给 时会自动释放*错误,并因此被 -[NSArray enumerateObjectsUsingBlock:] 的自动释放池回收。

有两种方法可以解决这个问题。第一个是在 block 外使用局部变量,使 ARC 保留它直到枚举完成:

- (BOOL)runMethodThatAssignsError:(NSError **)error {
__block NSError *_error = nil;

[@[@1] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
_error = [NSError errorWithDomain:@"1" code:7 userInfo:@{}];
}];

if (error) *error = _error;

return NO;
}

或者,您可以只将error 参数声明为__strong,这将防止NSError 被放入第一名。请注意,仅当此方法的客户端始终使用 ARC 时才应执行此操作,否则可能会导致错误泄漏,因为由于此方法非常规,客户端不会期望必须释放它们。

- (BOOL)runMethodThatAssignsError:(NSError * __strong *)error {
[@[@1] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (error) *error = [NSError errorWithDomain:@"1" code:7 userInfo:@{}];
}];

return NO;
}

关于objective-c - 在 block 崩溃中分配 NSError 的调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45923106/

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