0

I am showing data in table view using NSFetchedResultsController. Now when data reaches from server I need to delete all data present in the sqlite database.

Now when I delete data from database using given below code it sometime crashes (not always) giving this error:

Execution_BAD-ACCESS (code=2, address=0x0)

on this line

if (![moc save:&saveError]) {

.h

@property (readonly, retain, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, retain, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, retain, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;

.m

@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;

NSManagedObjectContext *moc = [delegate managedObjectContext];

NSFetchRequest * allCategories = [[NSFetchRequest alloc] init];
[allCategories setEntity:[NSEntityDescription entityForName:@"Categories" inManagedObjectContext:moc]];
[allCategories setIncludesPropertyValues:NO]; //only fetch the managedObjectID

NSError * error = nil;
NSArray * dataArray = [moc executeFetchRequest:allCategories error:&error];

//error handling goes here

[NSFetchedResultsController deleteCacheWithName:@"RootDetail"];

for (Categories *cat in dataArray) {
    [moc deleteObject:cat];
}

NSError *saveError = nil;      
if (![moc save:&saveError]) {
    NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
}

[allCategories release];

I check throughly now i found that this problem is coming when i vist the DetailPageController and go back(using UINavigationController popNavigationController:) and then if i wist DetailPageController then it crashes.

giving following errror -[DetailPageController controllerWillChangeContent:]: message sent to deallocated instance 0x11f52a90*


The problem is of NSManageObjectContext. So the fix is always use new created object of NSManageObjectContext otherwise it will create problems.


Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Iqbal Khan
  • 4,587
  • 8
  • 44
  • 83
  • Execution bad access typically means an object has been deallocated prematurely. How is your moc property defined in your app delegate? – occulus Mar 16 '13 at 09:09
  • A little late but adding my 2cents. Make sure you setting the delegate for the fetch result controller back to nil in the dealloc method of your uiviewcontroller. – user281300 Dec 23 '14 at 13:59

2 Answers2

2

Based on your comment

I am using operation queue. so i enter data on main thread. 2. you are saying that each thread should have separated instance of context. But i think there should be only one main instance of context.

No. You MUST follow the documentation about Concurrency with Core Data

Create a separate managed object context for each thread and share a single persistent store coordinator. This is the typically-recommended approach.

or

Create a separate managed object context and persistent store coordinator for each thread. This approach provides for greater concurrency at the expense of greater complexity (particularly if you need to communicate changes between different contexts) and increased memory usage.

or

use new Core Data APIs.

Original question

If you provide some other details about the crash, I think we can help you. What about delegate?

In the meantime, some hints for you.

1) Enable zombies in Xcode

How to enable NSZombie in Xcode?

2) Use the right context

Why do you use the following?

NSManagedObjectContext *moc = [delegate managedObjectContext];

just use

NSManagedObjectContext *moc = [self managedObjectContext];

This could be the origin of the problem. But without details I'm not very sure.

So, when you create this controller from external, set the managed object context property correctly.

yourController.managedObjectContext = theContextYouWantToShare;

3) Error handling

NSError * error = nil;
NSArray * dataArray = [moc executeFetchRequest:allCategories error:&error];
if(dataArray) {
    // manage objects here...
} else {
    // handle error here...
}
Community
  • 1
  • 1
Lorenzo B
  • 33,216
  • 24
  • 116
  • 190
  • there will be only one instance of NSManageObjectContext in the application. so if i get it from delegate or setIt in the view controller while initializing then will it can create any problem. – Iqbal Khan Mar 18 '13 at 07:14
  • when i enable NSZombie then error is Now, the app won't load the dashboard and it crashes on 2nd visit to the screen not on first. *** -[DetailPageController controllerWillChangeContent:]: message sent to deallocated instance 0x11f52a90 – Iqbal Khan Mar 19 '13 at 06:47
0

The answer by flexaddicted is very good (unfortunately I can't comment yet) but remember to be very careful if you have a multi-threaded application (you mention server calls in your question). Make sure that each thread uses its own context, otherwise you will run into problems. This is well docmented in Apple's Core Data documentation.

Or, at the very least, make sure that any call to do something with core data is on the main thread (although this is not ideal as this can block when performing long operations).

miwic
  • 70
  • 1
  • 6
  • 1. I am using operation queue. so i enter data on main thread. 2. you are saying that each thread should have separated instance of context. But i think there should be only one main instance of context. – Iqbal Khan Mar 18 '13 at 07:17
  • To test which thread the core data operations are run on, you can add [NSThread isMainThread] when calling core data operations. Apple's docs have more info: http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/CoreData/Articles/cdConcurrency.html. In this link it does say 'The pattern recommended for concurrent programming with Core Data is thread confinement: each thread must have its own entirely private managed object context. But, I don't know if this is the problem. Try checking what thread you're calling coredata operations on and try suggestions from flexaddicted. – miwic Mar 18 '13 at 12:22