重用同一个 NSError 对象会有问题吗?

Posted

技术标签:

【中文标题】重用同一个 NSError 对象会有问题吗?【英文标题】:Can reusing the same NSError object be problematic? 【发布时间】:2014-08-28 21:37:28 【问题描述】:

我已经将我的实现更改为不再这样做了,但我很想知道以下是否会导致问题 - 例如一个有多个步骤的流程,每个步骤都涉及传递对 NSError 对象的引用。如果您在此过程中的每一步都重用此错误对象,该引用是否会以某种方式受到负面影响,可能导致某种内存管理/dealloc 崩溃?

示例(大部分中间代码已被省略)

    NSError *error;
    NSData *data = [NSJSONSerialization dataWithJSONObject:object options:0 error:&error];

    if (!data) 
        return error;
    

    NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

    if (!responseData) 
        return error;
    

    NSDictionary *resultDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error];

    if (!resultDictionary) 
        return error;
    

即使错误从未“使用”两次,这意味着下次将其引用传递给另一个方法时错误将为零(似乎),该引用是否会在任何步骤中以某种方式受到影响怎么办?

响应 jlehr 的 cmets 编辑前的原始代码:

    NSError *error;
    NSData *data = [NSJSONSerialization dataWithJSONObject:object options:0 error:&error];

    if (error) 
        return;
    

    NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

    if (error) 
        return;
    

    NSDictionary *resultDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error];

    if (error) 
        return;
    

编辑:对于以后来这里的任何人,可以在此处找到 jlehr 所指的信息:

在处理通过引用传递的错误时,测试很重要 方法的返回值,看是否发生错误,如 如上所示。不要只是测试是否设置了错误指针 指向错误。

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/ErrorHandling/ErrorHandling.html

【问题讨论】:

根据 Apple 的文档,您永远不应该检查引用返回的 NSError 对象;而是检查返回值。 有趣,你有链接到文档中的位置吗?检查返回值是什么意思? 没关系,我现在明白你说的返回值是什么意思了..脑子放屁.. 【参考方案1】:

根据 Apple 的文档,您永远不应该检查引用返回的 NSError 对象。相反,请检查您正在调用的 init... 方法或工厂方法的返回值,例如:

NSError *error;
NSData *data = [NSJSONSerialization dataWithJSONObject:object options:0 error:&error];
if (data == nil) 
     // Handle failure. It's safe to use the error object here.

但是,您的代码似乎没有对 NSError 实例执行任何操作(例如,记录或显示警报),因此您可以改为传递 NULL

NSData *data = [NSJSONSerialization dataWithJSONObject:object options:0 error:NULL];
if (data == nil) 
     // Handle failure.

【讨论】:

我的代码实际上做了很多事情,包括日志记录、分析以及将错误作为块中的参数返回,我只是在这个例子中省略了。 感谢您的回复,所以除此之外,我的主要问题围绕着重复使用相同的错误对象。如果我将对它的引用传递给所有这些方法,并且它们都可以正常工作,但是在最后一个方法中出现错误,即使没有发生错误,错误对象是否会受到重复引用传递的影响? 你没有传递一个错误对象——你传递了一个未初始化的局部变量的地址,所以这个问题真的没有意义。 变量未初始化。这意味着该地址处的值未定义,因此更改该值没有任何意义。您传递地址,以便在发生错误时,您调用的方法可以为您将对象的地址写入变量中。由于无法保证如果发生错误 doesn't 时该方法不会将垃圾写入地址,Apple 的文档说测试错误变量的值是不安全的。鉴于在发生错误之前您无法安全地使用该变量,因此您之前是否将地址传递给另一个方法并不重要。 请注意,以令人困惑的方式编写代码更有可能导致错误。如果您觉得代码为每次调用定义不同的错误变量会更清晰,那么请务必这样做。

以上是关于重用同一个 NSError 对象会有问题吗?的主要内容,如果未能解决你的问题,请参考以下文章

我可以在 Objective-C 的 init 中包含 NSError** 作为参数吗?

带有 NSFetchedResultsControllers 的 NSError 对象

我可以重用代码来为 EF Core 的子属性选择自定义 DTO 对象吗?

如何跨线程跟踪 NSError 对象?

如何将 NSstring 转换为 NSerror 对象类型

AFNetworking 在 NSError 对象中返回响应