Can reusing the same NSError object be problematic

2019-09-10 03:47发布

问题:

I have since changed my implementation to not do this anymore, but I would be interested in knowing if the following could lead to issues - take for example a process that has multiple steps, each involving passing a reference to an NSError object. If you were to reuse this error object each step along the way, would that reference be negatively effected in some way, perhaps leading to some sort of memory management/dealloc crash?

Example (most of the in-between code has been omitted)

    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;
    }

Even though the error is never "used" twice, meaning the error will be nil (it seems) the next time its reference is passed to another method, could the reference be effected in some way at any of the steps along the way?

Original code prior to editing in response to jlehr's comments:

    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;
    }

EDIT: To anyone coming to this at a later date, the information jlehr is referring to can be found here:

When dealing with errors passed by reference, it’s important to test the return value of the method to see whether an error occurred, as shown above. Don’t just test to see whether the error pointer was set to point to an error.

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

回答1:

According to Apple's documentation, you should never check an NSError object returned by reference. Instead, check the return value of the init... method or factory method you're calling, for example:

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.
}

However, your code doesn't appear to be doing anything with the NSError instance, (e.g., logging, or displaying an alert), so you can just pass NULL instead.

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