0

Here is my code:

void autoreleasingReturn (NSError * __autoreleasing *error)
{
    // --- Crashing
    *error = [[NSError alloc] init];

    // --- Not crashing
//    *error = [NSError errorWithDomain:@"hello"
//                                 code:-1
//                             userInfo:@{}];
}

int main(int argc, const char * argv[])
{

    @autoreleasepool {

        NSError __strong *error = nil;

        autoreleasingReturn(&error);

        NSLog(@"error: %@", error); // crash!
    }

    return 0;
}

Traces (sorry, can not copy-paste):

enter image description here

The question is: what is going on?

I need details on what is going on in this code. Really interesting... Instruments don't show any leaks, zombies etc.

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
AndrewShmig
  • 4,843
  • 6
  • 39
  • 68

1 Answers1

2

initWithDomain:code:userInfo: is the designated initializer for NSError. That means don't call plain init.

You would get the same crash just by saying this:

NSLog(@"%@", [[NSError alloc] init]);

The problem has nothing to do with automatic ref counting, autorelease, autorelease pool, strong, or any of that other stuff! It's just that you are making a bad NSError object and then trying to log it.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Can you explain me, whats going there under the hood? – AndrewShmig May 03 '13 at 17:34
  • 1
    Yes, I can! :) NSLog is crashing you. You're making an invalid NSError object. When you try to log it, NSLog sends your NSError object the `description` message. But it is invalid so it has no `description`. – matt May 03 '13 at 18:47
  • 1
    (Well, it has a `description` method, but that method calls `localizedDescription` and that's the source of the problem.) – matt May 03 '13 at 18:57
  • 2
    I would argue that this is a library bug. It should throw an exception, either at initialization time, or at `description` time. – newacct May 03 '13 at 20:45
  • Or `init` should call the designated initializer with reasonable default arguments. I'll file a bug if you will! – matt May 03 '13 at 20:53
  • We investigated the same error, `[[NSError alloc] init]` creates a broken `NSError` object, that crashes when calling `-description` or `-localizedDescription`. The fact that `-initWithDomain:code:userInfo:` is the designated initializer doesn't mean by any way that using other initializers is bad. The framework should either properly handle `NSError`s without `domain` or raise an exception when initializing an `NSError` without domain. – Micha Mazaheri Mar 25 '15 at 13:53