开发者

NSManagedObjectContext doesn't refresh correctly

开发者 https://www.devze.com 2023-03-27 00:26 出处:网络
hi :) I have a similarly issue like in Working with the same NSManagedObjectContext in multiple tabs

hi :) I have a similarly issue like in Working with the same NSManagedObjectContext in multiple tabs

background:

My managedObjectContext (further MOC) is initialised in my appDelegate class and passed throught to multiple tabs by

myViewController.managedObjectContext = self.managedObjectContext; or in the init method with self.managedObjectContext = pContext; the flow is: the first view is a simple list of collections. The collections are fetched with a NSFetchedResultsController (myViewController : UITableViewController<NSFetchedResultsControllerDelegate>). By selecting one, you navigate deeper, but still passing this MOC.

In the next controller (detailsViewController) I list up some items of this collection what I can interact with (set switches for instance).

I also have an editingObjectContext:

// DetailsViewController.m
NSManagedObjectContext* editingContext = [[NSManagedObjectContext alloc] init];
[editingContext setPersistentStoreCoordinator:[managedObjectContext persistentStoreCoordinator]];
self.editingObjectContext = editingContext;

Now my issue: because my view has to rotate, I am using the folowing trick:

// DetailsViewController.m
DetailsView *localAct = [[DetailsV开发者_JS百科iew alloc] initWithManagedObjectContext:managedObjectContext ... ]
DetailsView *localSen = [[DetailsView alloc] initWithManagedObjectContext:managedObjectContext ... ]

UITableView *localContainerView = [[UITableView alloc] init];
self.containerView = localContainerView;
[localContainerView release];
//[...]
[containerView addSubview:actuatorView];
self.tableView = containerView;

further I have a button to manage this items (which of them shall be shown and which not). This button just reloads the table with a new fetchResult.

// DetailsView.m
- (void) manageItems{
managing = !managing;
[viewController setIsManaging:managing]; // parent
self.fetchedResultsController = nil;

NSError *error = nil;
[[self fetchedResultsController] performFetch:&error];

[self reloadData];
[self updateBarButton];
}

The method for putting the items into the context looks so:

// DetailsViewController.m
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// init + create predicate
NSSet* set = [sen filteredSetUsingPredicate:predicate];
if( [set count] > 0 )
{
    for( Act* act in set )
    {
        [editingObjectContext deleteObject:act];
    }
}
else
{
    Act* act = [NSEntityDescription insertNewObjectForEntityForName:@"Act" inManagedObjectContext:editingObjectContext];

    // do things
}
NSError *error = nil;
[[detailView fetchedResultsController] performFetch:&error];

[self.containerView reloadData];
[detailView reloadData];
}

but after I selected the items in the managed view and clicked save (manageItems), the view doesn't show them :/ i have to switch the tab or to navigate in an other controller (parent or deeper) to actualize it. my ViewWillAppear method:

// DetailsViewController.m
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
DetailsView *detailView = se ? senView : actView;
// [do uninteresting stuff]
[detailView.fetchedResultsController performFetch:nil];
[self.tableView reloadData];
// [do uninteresting stuff]
}

and viewWillDisapper calls

- (void)saveChanges
{
if( ![editingObjectContext hasChanges] )
    return;

// send save-command to server
}

In an earliert Verison where there was only 1 view it worked and I haven't changed realy much... :/ so I don't understand why the MOC is acting like it does. The "manageItems" part is nearly equal, its just a level deeper in the new version (in the DetailsView instead of the controller) ...

if someone can tell me what I can try (always saving to server when switch between managing and normal isn't a solution because the delay in the response from the server is to high for the refresh, so I have the less to flip the view. Also refreshing the views with self.tableView / detailView / self.containerView refresh brings the same result :/ ).

and a second issue: I can't call the "editingObjectContext save:" method after sending to server, because it's throwing errors and don't save at all to local database.

Error in handleChangeResponse: Error Domain=NSCocoaErrorDomain Code=133020 "The operation couldn’t be completed. (Cocoa error 133020.)" UserInfo=0x4d8bb90 {conflictList=( "NSMergeConflict (0x5a2fac0) for NSManagedObject (0x5a46a80) with objectID '0x5a46420 ' with oldVersion = 7 and newVersion = 8 and old object snapshot = {\n iconName = noicon;\n [...] ;\n} and new cached row = {\n iconName = noicon;\n [...] \n}" )}

if you have questions or need some more code (i.e. of the older version) then just ask ;)

thanks in anticipation :)


It seems like I have the solution! Since IOS 5.0 there is a new method for NSManagedObjectContext :

[managedObjectContext setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];

Found on http://pauloliveira.net/tech/core-data-merging-conflicts
Setting this attribute to the top-level MOC (in my case in the appDelegate) and no-where else! clears my merging problems ;)


I found the reason why it doesn't worked... forget everything what I wrote above... the problem was in the fetchrequest - concretely: in the predicate... in the earlier versions I used

[NSComparisonPredicate predicateWithLeftExpression: ...] 

in the actualy version I use

NSString * predicateFormat = [NSString stringWithFormat: ...];
NSPredicate* predicate = [NSPredicate predicateWithFormat:predicateFormat];

because I had to extend the number of options and also edited the request itself because it made problems in the predicate (comparing a complete object (of the MOC class, extracted from the database) with an entity didn't worked, so I managed the workaround in the DetailsViewController and haven't rolled back my updates in this place :/).
Never thought to waste so much time on this problem >.< but okay, as long as it's resolved :D

I will check if the second issue (with the saving problem) still exists. If not, I will update my post, otherwise this topic isn't closed :/


This may be due to manageobject context in use of object where u'r getting this. Remove all NSManagebobject at the time when you either log out or move back. say end using app. Seems like this...

[NSManagebobjectcontext setManagedObjectsDictionary:[NSMutableDictionary dictionary]];
0

精彩评论

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

关注公众号