2011-05-01 13 views
3

更新のために私のアプリケーションを準備する際に、私はこれまでの頭を傷つけた人の奇妙な問題を発見しました。管理されたオブジェクトのコンテキストの保存が永続的なストアになりません

私は管理対象オブジェクトを取り出し、1つの属性を更新し、その変更を永続ストアに保存する簡単な方法を持っています。変わったことは、実際にはスタックの下にあるDBにすべて保存されていないようですが、保存に成功した場合にtrueを返し、NSErrorオブジェクトに値を設定しません。

SQLロギングを有効にすることでこれを確認しました.1回の呼び出しでUPDATE文は表示されませんが、同じ入力の同じメソッドの2回目の呼び出しでUPDATEが表示されます。

本当に奇妙です。私は間違ったことをする必要がありますが、私は一日中これを見つめており、私はそれを理解できません。ここで

+ (void)markTemplateAsPurchasedWithProductID:(NSString *)productID inContext:(NSManagedObjectContext *)context {  
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"TripTemplate" inManagedObjectContext:context]; 
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"(productID = %@)", productID]]; 
[fetchRequest setEntity:entity]; 
NSError *error; 
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error]; 
[fetchRequest release]; 

if ([fetchedObjects count] > 0) { 
    TripTemplate *template = [fetchedObjects lastObject]; 
    template.purchased = [NSNumber numberWithBool:YES]; 

    NSLog(@"Marking '%@' as Purchased: %@", template.name, template.purchased); 

    NSError *saveError;   
    if (![context save:&saveError]) 
     NSLog(@"Error Saving Purchased For Template: %@ - %@", template, saveError); 
} else { 
    ... 
    //log fetch error 
} 
} 

は、このメソッドを呼び出すときに、私が見たログの二組です:

は、ここで問題になっている方法です。

私は両方のケースでメインスレッドから呼び出されていることを確認しました。

これらは順番に実行されています。

ラン#1(なしSQLの更新):

2011-04-30 17:25:27.107アプリ[15024:707] CoreData:SQL:0]を選択し、t0.Z_PK、t0.Z_OPT、 t0.ZAUTHORURL、t0.ZAUTHORURL、t0.ZAUTHORNAMEからZTRIPTEMPLATE t0どこにt0.ZPRODUCTID =?

2011-04-30 17:25:27.110アプリ[15024:707] CoreData:注釈:0.0028s

2011-04-30 17:25:SQL接続時間をフェッチ27.111アプリ[15024:707 ] CoreData:注釈:総フェッチ実行時間:1行につき0.0043s。

2011-04-30 17:25:27.112アプリの[15024:707]購入した 'スティーブのクリエーションズ' をマーキング:1

ラン#2(SQL更新):

2011-04 -30 17:27:37.536アプリケーション[15024:707] CoreData:sql:SELECT 0、t0.Z_PK、t0.Z_OPT、t0.ZLASTAPPSTOREPRICE、t0.ZPURCHASED、t0.ZISFREE、t0.ZNAME、t0.ZPRODUCTID、t0。 ZSERVERID、t0.ZTRIPDESCRIPTION、t0.ZAUTHORDESCRIPTION、t0.ZAUTHORURL、t0.ZCREATEDAT、t0.ZAUTHORNAMEからZTRIPTEMPLATE t0どこにt0.ZPRODUCTID =?

2011-04-30 17:27:37.537アプリ[15024:707] CoreData:注釈:0.0015s

2011-04-30 17:27:SQL接続時間をフェッチ37.538アプリ[15024:707 ] CoreData:注釈:総フェッチ実行時間:1行につき0.0024秒。

2011-04-30 17:27:37.539アプリの[15024:707] 'スティーブのクリエーションズ' 購入としてマーキング:1

2011-04-30 17:27:37.540アプリの[15024:707] CoreDataを:sql:BEGIN EXCLUSIVE

2011-04-30 17:27:37。542 App [15024:707] CoreData:SQL:UPDATE ZTRIPTEMPLATE SET ZPURCHASED =?、Z_OPT =?どこZ_PK =? AND Z_OPT =?

2011-04-30 17:27:37.544アプリの[15024:707] CoreData:SQL:私は私の問題を探し始めるかもしれません

任意の提案をCOMMIT?

両方の場合、フェッチが機能するので、MOCは少なくとも店舗と話すことができます。

+0

SQLログに依存して、何も変更されていないこと、または管理対象オブジェクト自体が変更されていないことを伝えていますか?再起動時に変更が表示されますか? – TechZen

+0

私は、検証のためにSQLログを使用しました。保存した前後で購入した属性をログに記録した場合はtrueと表示されますが、保存後にオブジェクトを更新すると '購入済み'属性はfalseに戻ります。 – Hunter

+0

複数のコンテキストまたは複数のスレッド/操作がありますか? – TechZen

答えて

1

コードを見ると、私がエラーとして示唆できるのは、何らかの形で別のコンテキストをメソッドに渡しているということだけです。その場合、コンテキストをマージしないと、1つに保存して別のコンテキストで調べると変更内容は表示されません。

テンプレートオブジェクト全体、コンテキスト、およびコンテキストのupdatedObjectsのロギングをお勧めします。あなたはあなたが思っている物と話していることを確認する必要があります。

+0

二重チェックに値するもののようなものです。私は脳が溶けている間ずっとこれを見てきました。それが危険な前提を作り始めるときです。報告する... – Hunter

+0

これは良いアドバイスでした。私は、あるコードパスでメソッドに渡されたMOCを混在させて、この不思議さを引き起こしていたことがわかります。だから、ユーザーエラーのかなり単純なケースであることが分かります。時々、あなたはそれを誰かと話すだけです。ありがとう! – Hunter

関連する問題