4

I am getting a crash on a iOS 7 app with the following error:

-[NSError release]: message sent to deallocated instance 0x3c443fe0

The error is initiated when I add a call to the following method:

-(void)loadMessages:(NSString*)customerUID {
  NSString *formatUID = [NSString stringWithFormat:@"%s%@%s", "'", customerUID, "'"];
  formatUID = [formatUID stringByReplacingOccurrencesOfString:@"'" withString:@"%27"];
  NSString *servicePath = [NSString stringWithFormat:@"/api/messagerecipient?messageid=null&customeruid=%@", formatUID];

  [[RKObjectManager sharedManager] getObjectsAtPath:servicePath parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *messagesResult)
  {
    NSArray *messageResults = messagesResult.array;

    if (messageResults != nil || [messageResults count] != 0)
    {
      //Add some code here
    }
  } failure:^(RKObjectRequestOperation *operation, NSError *error) {

    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"An Error Has Occurred" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alertView show];
  }];
}

I added multiple breakpoints into the code at various points, and it's not returning any error details. Also, nothing in the console log indicates what the problem is (I have added full RestKit logging), just the above NSError release message.

I have also run a Zombie scan in Instruments. It shows the following.

Instruments

I'm confused because this shows that the zombie is being created by a GSEventRunModal call. When I go to Extended Detail and select the call, it shows the following:

Extended Detail

Any pointers would be gratefully appreciated, thanks.

Update: Instrument Extended Details stack trace

enter image description here

Dancer
  • 17,035
  • 38
  • 129
  • 206
  • So what makes you think this is RestKit related? If you don't make that RestKit call then you don't have issues? – Wain Mar 17 '14 at 20:37
  • Yes, that's correct, not sure if it is related to RestKit though. The last breakpoint that is hit is in AFURLConnectionOperation, operationDidStart method. The process that seems to be throwing the error is _CFRunLoopRun. – Dancer Mar 17 '14 at 21:05
  • Your mapping should create managed objects and insert to the store? What unsaved content do you have when making this request? What else are you doing with Core Data at the same time? – Wain Mar 17 '14 at 21:09
  • It would be useful to see the entire stack trace from the extended detail pane, for the site where the `NSError` was allocated. – rob mayoff Mar 17 '14 at 21:29
  • 1
    The zombie isn't being created by `GSEventRunModal`. When you see a Release in `GSEventRunModal`, that is an autorelease pool being drained. The last line in your event history (line 7) is an extra release (being sent to the `NSError` that became a zombie in line 6) because the `NSError` was autoreleased too many times. – rob mayoff Mar 17 '14 at 21:32
  • The controllers ManagedObjectContext has no changes prior to the method call. The console log is showing that the object mapping operation was successful, but no objects are being added to the store. Also, there is no log of the get request/response headers to/from the service. – Dancer Mar 17 '14 at 21:36
  • I've added the extended details stack trace now to the original post. – Dancer Mar 17 '14 at 21:56
  • Can you share your implementation of 'getObjectsAtPath' method ? – Bikramjit Singh Mar 24 '14 at 20:44
  • the link for this issue might help solve your problem https://github.com/RestKit/RestKit/issues/1140 Renaming HTTPError to HTTPError1 and making the property @synthesized solves the problem – vin Mar 26 '14 at 06:55
  • where does this error occur ? in the successBlock ? errorBlock ? or before any of these are called ? – nsuinteger Mar 26 '14 at 17:37

5 Answers5

2

I've seen this a lot as well and the root of the problem appears to be in Core Data. I use the MagicalRecord database library (so does RestKit) and we thought the error was there. You can see a discussion here. After all of our investigation it seemed like MagicalRecord was right and Core Data was at fault.

This had actually been filed as a bug that Apple claimed to have fixed, but we are still seeing it. The only way I've been able to work around this is by preventing every instance where I might not be able to save data so no error is reported. You can see some of those tips in the discussion thread linked to above.

Mike Gottlieb
  • 966
  • 6
  • 11
  • although it hasnt solved my issue - your answer has gone a good way to explaining what is going wrong - hence awarding you the bounty.. Cheers for your help! – Dancer Mar 27 '14 at 17:45
0

Could it be that you are trying to display an AlertView from inside a block? Interaction with the UI has to be on the main thread?

How do display a UIAlertView from a block on iOS?

Community
  • 1
  • 1
Flexicoder
  • 8,251
  • 4
  • 42
  • 56
0

Can you try to replace:

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"An Error Has Occurred" message:[error localizedDescription] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alertView show];

With:

NSString * message = [error localizedDescription];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"An Error Has Occurred" message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alertView show];

Although I guess that the init method is getting a string anyway.

Rivera
  • 10,792
  • 3
  • 58
  • 102
0

i think your problem is not with the method it self.

the error message says that you are sending a release call to an object of the type NSERROR.

please check the instance of the class which contains the method you are calling and make sure it's not deallocated.

or add the calling method to the question in order for us to check it.

Ahmad Al-Attal
  • 435
  • 4
  • 13
0

In my case threading the database to a separate context helped. I used the following constructor on the class that was receiving the message:

    -(id)init {
    self = [super init];
    if (self) {
        self.managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
        self.managedObjectContext.parentContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
        self.managedObjectContext.retainsRegisteredObjects = YES;
    }

    return self;
}
Jake Hargus
  • 352
  • 3
  • 11