2011-08-08 5 views
5

ハイテクをリフレッシュしません:)私は同様のように発行していでWorking with the same NSManagedObjectContext in multiple tabs
背景:
マイmanagedObjectContext(さらにMOC)私のappDelegateクラスで初期化し、
myViewController.managedObjectContext = self.managedObjectContext;かによって、複数のタブにthroughtを渡されますself.managedObjectContext = pContext; のinitメソッドでは、フローは次のようになります。最初のビューは単純なコレクションのリストです。コレクションはNSFetchedResultsController(myViewController : UITableViewController<NSFetchedResultsControllerDelegate>)で取得されます。 1つを選択すると、より深くナビゲートしますが、このMOCは引き続き通過します。
次のコントローラ(detailsViewController)では、このコレクションのいくつかの項目をリストアップします(たとえば、スイッチの設定など)。
NSManagedObjectContextは正しく

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

今私の問題:私はまたeditingObjectContextを持って
私のビューが回転しているので、私はfolowingトリックを使用しています:

さらに
// 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は、それが働いただけで1つのビューがあったearliert Verisonで

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

// send save-command to server 
} 

を呼び出して、私は...本当にあまり変わっていない:/ので、私ドンなぜMOCがそれと同じように動作しているのか理解できません。 「manageItems」の部分はほぼ同等です。コントローラの代わりにDetailsViewの新しいバージョンのほんの一層のレベルです...

誰かが私に何を試せるか教えてくれたらサーバーからの応答の遅れがリフレッシュのために高くなるため、管理者と通常の間の解決策はありません。したがって、私はビューを反転する必要がありません。またself.tableView/detailView/self.containerView refresh同じ結果をもたらす:/)。

2番目の問題:サーバーに送信した後で、「editingObjectContext save:」メソッドを呼び出すことはできません。エラーをスローしてローカルデータベースに一切保存しないためです。 handleChangeResponseで

エラー: "操作は完了できなかった(ココアエラー133020.)" エラードメイン= NSCocoaErrorDomainコード= 133020のUserInfo = 0x4d8bb90 {conflictList =( 「NSMergeConflict(0x5a2fac0)NSManagedObject用(古いバージョンのオブジェクトスナップショット= {\ n iconName = noicon; \ n [...]; \ n}と新しいキャッシュ行= {\ n iconName = noicon; objectID = 0x5a46420) \ n [...] \ nを}」 )}

質問があるか、そしてちょうど頼む)古いバージョンのつまり(いくつかのより多くのコードが必要な場合;)見越して

おかげで:)

+0

大丈夫、フリップビューで作業しているバージョンが見つかりました...既に新しいものにコードをコピーしましたが、それと同じ問題があります:/ ' - (void)manageItems/* DetailsViewController */ { \t詳細ビュー* detailView = isSen? senView:actView; \t [detailView manageItems]; ! } ' --- ' - (無効)manageItems //たDetailsView { \t管理=管理; \t [ビューコントローラsetIsManaging:管理];/* parent */ \t self.fetchedResultsController = nil; \t NSError * error = nil; \t [[self fetchedResultsController] performFetch:&error]; \t [viewController.containerView reloadData]; \t [self updateBarButton]; } ' – geo

答えて

6

私は解決策を持っているようです! (appDelegateで私の場合は)トップレベルのMOCと無他にどこにこの属性を設定http://pauloliveira.net/tech/core-data-merging-conflicts
に見つかり

[managedObjectContext setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy]; 

:IOS 5.0以来NSManagedObjectContextのための新たな方法があります! )

+0

setMergePolicy:はiOS 3.0から利用できます – rowwingman

0

私が見つかりました。述語で...私は

[NSComparisonPredicate predicateWithLeftExpression: ...] 

を使用し、以前のバージョンで:具体的 - それは働いていない理由は...問題はfetchrequestにあった...私は上記の書いたものすべてを忘れます実際のverシオンIオプションの数を拡張しなければならなかったし、また、それは()でデータベースから抽出されたMOCクラスの完全なオブジェクトを(比較述語の問題を作っているため、要求自体を編集したので、私は

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

を使用エンティティは機能しませんでしたので、DetailsViewControllerの回避策を管理しましたが、ここで更新をロールバックしていません。
この問題で時間を無駄にすることは決して考えられませんでした。 <でも問題が解決されていれば問題ありません。D

2番目の問題(保存に関する問題あり)がまだ存在するかどうかを確認します。そうでない場合、投稿を更新します。そうでなければ、このトピックは閉じられません。/

0

これは、オブジェクトを使用してオブジェクトを使用しているためです。ログアウトするか、戻ったときにすべてのNSManagebobjectを削除します。アプリケーションを使用して終了を言う。このように...

[NSManagebobjectcontext setManagedObjectsDictionary:[NSMutableDictionary dictionary]];