开发者

Problem with NSManagedObjectContextObjectsDidChangeNotification in two different views

开发者 https://www.devze.com 2023-03-04 02:34 出处:网络
Good evening everyone, before explaining my problem, I should give you some explanation on my project first :

Good evening everyone,

before explaining my problem, I should give you some explanation on my project first :

I have a simple Coredata model with one entity called "Conversation" and the other one "Message". Basically, I need to kind of reproduce the iPhone sms application.

Conversation{  
    messages<-->>Message.conversation  
}  

Message{  
    conversation<<-->Conversation.messages  
}    

As you can see, my model is easy to understand. I asked some help a few weeks ago about how to implement these views altogether (i.e. using NSFetchedResultsController (FRC) or not in the view displaying messages from a specific conversation on this post.

So Wh at i did is that I use one FRC in each view. Another thread is from time to time updating my model. In order to notify my views that my model changed, I used this in my second thread :

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];  
[nc addObserver:self
       selector:@selector(mergeChanges:)
           name:NSManagedObjectContextDidSaveNotification
         object:_context];  

And the mergeChanges: function is doing this :

- (void)mergeChanges:(NSNotification *)notification {  
AppDelegate *appDel = (AppDelegate*)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *mainContext = [appDel managedObjectContext];

// Merge changes into the main context on the main thread
[mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
                              withObject:notification
                           waitUntilDone:YES];  
}  

This code was I thought working great because in both viewController (lets call them ConversationVC (where every conversations are listed) and MessageVC (where every messages from a specific conversations are listed)), I used :

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller;
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath;
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller;  

My Problem however is the following :

When I'm inserting new messages in my second thread and the context is saved, the notification is sent to both views, even if the MessageVC is not being displayed. It's not a property of my ConversationVC so when it gets poped, its value should be ni开发者_如何学JAVAl. (I think).

My question is : why is this sent to a view not being displayed ? I can't see it's value in the debugger anywhere. I tried to make it a property of the view and then assigned "nil" to it when coming back to the ConversationVC, but then I get a SIGBRT error saying that the notification was sent to a deallocated variable (which was logical).

I really need it to be sent only to the view currently displayed. Do you have any idea ?

Thank you very much


Okay... let me ask one question: does the view get displayed and THEN hidden - i.e. did you forget to tell it to STOP observing the notifications?


This might help some people :

For that issue, I didn't forget to call [NSNotificationCenter removeObserver:] because the method I was talking about where :

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller;
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath;
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller;  

These methods belongs to the NSFetchedResultsControllerDelegate. Basically, whenever a change is made to CoreData, and that your NSFetchedResultsController binds on the changed data, the delegate is called somehow, and calls these three methods.

What I did was :

- (void) viewDidDisappear {
    self.fetchedResultsController = nil; // using the property !
}

like that, if it gets called, the message will be sent to nil, which is authorized, and not to a deallocated instance variable.

0

精彩评论

暂无评论...
验证码 换一张
取 消