NSManagedObjectContext 无法正确刷新

发布于 2024-11-28 21:29:56 字数 4209 浏览 0 评论 0原文

嗨:)我有一个类似的问题,例如 使用相同的 NSManagedObjectContext在多个选项卡中
背景:
我的 ManagedObjectContext (进一步的 MOC)在我的 appDelegate 类中初始化,并通过
传递到多个选项卡 myViewController.managedObjectContext = self.managementObjectContext; 或在 init 方法中使用 self.managementObjectContext = pContext; 流程是:第一个视图是一个简单的集合列表。使用 NSFetchedResultsController (myViewController : UITableViewController) 获取集合。通过选择一个,您可以更深入地导航,但仍然会通过此 MOC。
在下一个控制器(detailsViewController)中,我列出了这个集合中我可以与之交互的一些项目(例如设置开关)。
我还有一个 editingObjectContext:

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

现在我的问题:因为我的视图必须旋转,所以我使用以下技巧:

// DetailsViewController.m
DetailsView *localAct = [[DetailsView 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;

此外,我有一个按钮来管理此项目(其中哪些应显示,哪些不显示)。此按钮只是使用新的 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];
}

将项目放入上下文的方法看起来是这样的:

// 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];
}

但是当我在托管视图中选择项目并单击保存(manageItems)后,视图不会显示它们:/我必须切换选项卡或在其他选项卡中导航控制器(父级或更深层)来实现它。 我的 ViewWillAppear 方法:

// 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]
}

和 viewWillDisapper 调用

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

// send save-command to server
}

在早期的版本中,只有 1 个视图可以工作,而且我并没有真正改变太多... :/ 所以我不明白为什么 MOC 的行为像它那样。 “manageItems”部分几乎是相同的,它只是新版本中更深的一层(在DetailsView而不是控制器中)...

如果有人可以告诉我我可以尝试什么(在管理和正常之间切换时总是保存到服务器 )不是一个解决方案,因为服务器响应的延迟对于刷新来说太高了,所以我翻转视图的次数较少,同时使用 self.tableView /DetailView/self.containerView 刷新刷新视图也会带来相同的结果。 :/)。

第二个问题:发送到服务器后我无法调用“editingObjectContext save:”方法,因为它会抛出错误并且根本不保存到本地数据库。

handleChangeResponse 中出现错误: 错误域 = NSCocoaErrorDomain 代码 = 133020 “操作无法完成。(Cocoa 错误 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} 和新的缓存行= {\n iconName = noicon;\n [...] \n}" )}

如果您有疑问或需要更多代码(即旧版本),请询问;)

谢谢您的期待:)

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 = [[DetailsView 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 :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

八巷 2024-12-05 21:29:56

看来我有解决办法了!从 IOS 5.0 开始,NSManagedObjectContext 有一个新方法:

[managedObjectContext setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];

可以在 http://pauloliveira.net/ 上找到技术/核心数据合并冲突
将此属性设置为顶级 MOC(在我的例子中是在 appDelegate 中),没有其他地方!解决了我的合并问题;)

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 ;)

橘虞初梦 2024-12-05 21:29:56

我找到了它不起作用的原因...忘记我上面写的所有内容...问题出在 fetchrequest 中 - 具体来说:在谓词中...在我

[NSComparisonPredicate predicateWithLeftExpression: ...] 

实际使用的版本中

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

使用的早期版本中,因为我必须扩展选项的数量,并且还编辑了请求本身,因为它在谓词中产生了问题(将完整的对象(从数据库中提取的 MOC 类)与实体进行比较是行不通的,所以我管理了解决方法在 DetailsViewController 中并且没有回滚我的更新在这个地方:/)。
没想到要在这个问题上浪费这么多时间>.<但是好吧,只要它得到解决:D

我会检查第二个问题(与保存问题)是否仍然存在。如果没有,我会更新我的帖子,否则这个主题不会关闭:/

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 :/

茶底世界 2024-12-05 21:29:56

这可能是由于在使用您获取此对象的对象时管理对象上下文。当您注销或返回时,删除所有 NSManagebobject。说结束使用应用程序。好像是这样的...

[NSManagebobjectcontext setManagedObjectsDictionary:[NSMutableDictionary dictionary]];

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]];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文