Closed travisjbeck closed 9 years ago
Can you show how you create the context you use to create the FRC?
Sent from my iPhone
On Jan 21, 2015, at 6:01 PM, travisjbeck notifications@github.com wrote:
I am creating a FRC with:
NSFetchedResultsController *controller = [Post MR_fetchAllSortedBy:@"expiration" ascending:YES withPredicate:pred groupBy:nil delegate:self inContext:context];
and saving data with:
[MagicalRecord saveWithBlock:^(NSManagedObjectContext localContext){ } completion:^(BOOL success, NSError error) { }]; The FRC delegate methods are never called in my UIViewController and the table data is blank until I leave the view and come back or reload the app.
— Reply to this email directly or view it on GitHub.
@Alydyn sorry, not sure if I understand..
@travisjbeck ok I see you added it now. What version of MR are you using?
I get the same thing in 2.2 and the current "develop" branch.
Some More Info. I added NSManagedObjectContextDidSaveNotification to get some more info:
-(NSManagedObjectContext *)context
{
if(!_context){
_context = [NSManagedObjectContext MR_defaultContext];
}
return _context;
}
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSArray *following = [[SessionManager getInstance].currentLoggedInUser.follows allObjects];
if(self.account){
//only show the posts for the account that was given
following = @[self.account];
}
NSDate *now = [NSDate date];
NSPredicate *pred = [NSPredicate predicateWithFormat:@"account IN %@ && expiration > %@", following, now];
NSFetchedResultsController *theFetchedResultsController = [Post MR_fetchAllSortedBy:@"expiration"
ascending:YES
withPredicate:pred
groupBy:nil
delegate:self
inContext:self.context];
NSError *error = nil;
[theFetchedResultsController performFetch:&error];
theFetchedResultsController.delegate = self;
self.fetchedResultsController = theFetchedResultsController;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contextChanged:) name:NSManagedObjectContextDidSaveNotification object:nil];
return _fetchedResultsController;
}
- (void)contextChanged:(NSNotification*)notification
{
DLog(@"contextChanged");
NSManagedObjectContext *context = [notification object];
if ([context isEqual:self.context]) {
DLog(@"same context");
return;
}else{
DLog(@"different context");
}
}
This is the output for the first time the app is ran when I get a blank tableview:
2015-01-22 12:19:18.415 alamode[43494:2720119] Created new private queue context: <NSManagedObjectContext: 0x7fe8b4bbffe0>
2015-01-22 12:19:18.425 alamode[43494:2720149] → Saving <NSManagedObjectContext (0x7fe8b4bbffe0): saveWithBlock:completion:> on a background thread
2015-01-22 12:19:18.425 alamode[43494:2720149] → Save Parents? YES
2015-01-22 12:19:18.425 alamode[43494:2720149] → Save Synchronously? NO
2015-01-22 12:19:18.425 alamode[43494:2720149] Context 'saveWithBlock:completion:' is about to save: obtaining permanent IDs for 22 new inserted object(s).
2015-01-22 12:19:18.427 alamode[43494:2720149] -[PostsViewController contextChanged:] [Line 92] contextChanged
2015-01-22 12:19:18.427 alamode[43494:2720149] -[PostsViewController contextChanged:] [Line 99] different context
2015-01-22 12:19:18.428 alamode[43494:2720152] → Saving <NSManagedObjectContext (0x7fe8b3d489a0): MagicalRecord Root Saving Context> on a background thread
2015-01-22 12:19:18.428 alamode[43494:2720152] → Save Parents? NO
2015-01-22 12:19:18.428 alamode[43494:2720152] → Save Synchronously? NO
2015-01-22 12:19:18.428 alamode[43494:2720152] Context 'MagicalRecord Root Saving Context' is about to save: obtaining permanent IDs for 22 new inserted object(s).
2015-01-22 12:19:18.429 alamode[43494:2720152] -[PostsViewController contextChanged:] [Line 92] contextChanged
2015-01-22 12:19:18.430 alamode[43494:2720152] -[PostsViewController contextChanged:] [Line 99] different context
2015-01-22 12:19:18.430 alamode[43494:2720152] → Finished saving: <NSManagedObjectContext (0x7fe8b3d489a0): MagicalRecord Root Saving Context> on a background thread
Looks like it never saves up to the "MR_defaultContext"
It won't "save up to the MR_defaultContext" because they are sibling contexts. It looks like this:
MagicalRecord automatically sets up MR_defaultContext
to observe save notifications from MR_rootSavingContext
. Your method will NEVER log "same context" the way you expect because, again, they are not parent/child MOC's but rather sibling contexts. In this scenario MR_defaultContext
is not actually saving but rather merging the save changes notification from MR_rootSavingContext
.
Check on StackOverflow. There are numerous issues regarding this, as well as closed issues here. Also try grabbing the newest release right from the release tab to make sure that have the latest. It should be 2.3beta5. There was a bug in earlier betas where the default context would not merge changes.
Also, out of curiosity, what happens if you re-fetch in the else?
- (void)contextChanged:(NSNotification*)notification
{
DLog(@"contextChanged");
NSManagedObjectContext *context = [notification object];
if ([context isEqual:self.context]) {
DLog(@"same context");
return;
}else{
DLog(@"different context");
[self.fetchedResultsController performFetch:nil]; // add this
}
}
Yeah, Im using 2.3.0-beta.5
If I add that line. The App hangs indefinitely.
If MR_defaultContext never gets notified of a change how will this EVER work?
Am I setting the FRC up wrong? Am I saving my data wrong?
There's obviously something I'm missing, I've done this exact same thing dozens of times before and never had this problem.
Have you turned on core data concurrency debugging?
Sent from my iPhone
On Jan 22, 2015, at 4:02 PM, travisjbeck notifications@github.com wrote:
Yeah, Im using 2.3.0-beta.5 If I add that line. The App hangs indefinitely.
If MR_defaultContext never gets notified of a change how will this EVER work?
Am I setting the FRC up wrong? Am I saving my data wrong?
Theres obviously something I'm missing, I've done this exact same thing dozens of times before and never had this problem.
— Reply to this email directly or view it on GitHub.
Not sure what that is.
On Jan 22, 2015, at 7:35 PM, Aaron Abt notifications@github.com wrote:
Have you turned on core data concurrency debugging?
Sent from my iPhone
On Jan 22, 2015, at 4:02 PM, travisjbeck notifications@github.com wrote:
Yeah, Im using 2.3.0-beta.5 If I add that line. The App hangs indefinitely.
If MR_defaultContext never gets notified of a change how will this EVER work?
Am I setting the FRC up wrong? Am I saving my data wrong?
Theres obviously something I'm missing, I've done this exact same thing dozens of times before and never had this problem.
— Reply to this email directly or view it on GitHub.
— Reply to this email directly or view it on GitHub.
When I add that it crashes after:
2015-01-23 08:29:38.602 alamode[54708:3776337] → Saving <NSManagedObjectContext (0x7ff9fb6059e0): MagicalRecord Default Context> on the main thread
2015-01-23 08:29:38.602 alamode[54708:3776337] → Save Parents? YES
2015-01-23 08:29:38.602 alamode[54708:3776337] → Save Synchronously? YES
On this line 105 in NSManagedObjectContext+MagicalRecord.m:
- (NSString *) MR_workingName
{
NSString *workingName = [[self userInfo] objectForKey:MagicalRecordContextWorkingName];//Crashes here
if ([workingName length] == 0)
{
workingName = @"Untitled Context";
}
return workingName;
}
You'll need to modify the MR_setWorkingName:
- (void) MR_setWorkingName:(NSString *)workingName
{
[self performBlockAndWait:^{
[[self userInfo] setObject:workingName forKey:MagicalRecordContextWorkingName];
}];
}
Still hangs on the same line
Then you are most likely accessing the context on the wrong queue. Wrap
you access in -performBlock:
and -performBlockAndWait:
On Fri, Jan 23, 2015 at 12:36 PM, travisjbeck notifications@github.com wrote:
Still hangs on the same line
— Reply to this email directly or view it on GitHub https://github.com/magicalpanda/MagicalRecord/issues/946#issuecomment-71241238 .
Sorry for my ignorance Aldyn, could you elaborate?
This is a really hard issue to troubleshoot because I feel like there is something else going on, specifically with respect to contexts or how you have set up your model/contexts. Generally speaking in my experience when you have a "hang" it is because you have a context waiting on something to happen somewhere else, which for me was caused by concurrency violations. Turning on concurrency debugging as outlined in that link is the first step. (And verify that it is indeed "hanging" and not throwing the concurrency violation exception).
Next I highly recommend starting simple and adding complexity. Create your NSFetchedResultsController
with NO predicate, execute the fetch, and then add and save new objects but this time use the same context as the FRC (MR_defaultContext
). When you verify that it works as intended, then add in the background context, but do it with only a few inserts, and try setting breakpoints in your -contextChanged:
method to verify that the objects are what you expect.
If none of that works then the only suggestion I have left is to make a simple project that reproduces your issue and I can take a look at it.
I finally figured it out. Thank you Alydyn for leading me down the right path. It was my predicate.
Glad to help. Can you close this issue then? Thanks!
I am creating a FRC with:
and saving data with:
The FRC delegate methods are never called in my UIViewController and the table data is blank until I leave the view and come back or reload the app.