1

だから、私は複数のスレッドでコアデータを使用しています。それぞれが独自の管理対象オブジェクト コンテキストを取得します。認識されないセレクター例外が発生するので、何か間違ったことをしていないか気になります。クラッシュは明らかに「mergeChanges」メソッドに関連しています。助けていただければ幸いです。

編集 myManagedObjectContext が割り当て解除されたオブジェクトを返すことが問題のようです。それはどうしてですか?

My code:

- (NSManagedObjectContext *) myManagedObjectContext {


    NSManagedObjectContext * result = [[[NSThread currentThread] threadDictionary] objectForKey: AQPerThreadManagedObjectContext];
    if ( result != nil )
        return result;

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator!=nil)
    {


    NSManagedObjectContext * moc = [[NSManagedObjectContext alloc] init];
    [moc setMergePolicy: NSMergeByPropertyObjectTrumpMergePolicy];
    [moc setPersistentStoreCoordinator: coordinator];
    [self StoreManagedObjectContextForCurrentThread:moc];
    [moc release];      // now owned by the thread dictionary
    return moc ;
    }
    else {
        GTMLoggerError(@"FAILED TO return managed object context ");

    }


    return nil; 
}

-(void) StoreManagedObjectContextForCurrentThread:(NSManagedObjectContext*) context
{
    [[[NSThread currentThread] threadDictionary] setObject: context forKey: AQPerThreadManagedObjectContext];
}

-(BOOL) saveChanges
{
    BOOL success = YES;
    NSManagedObjectContext* moc = [self myManagedObjectContext];

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 

    [nc addObserver:self
           selector:@selector(mergeChanges:)
               name:NSManagedObjectContextDidSaveNotification
             object:moc];

        NSError *error = nil;
        if ([moc save:&error] == NO)
        {
                    success = NO;
            GTMLoggerError(@"Failed to save to data store: [%@], [%@]", 
                           [error localizedDescription],
                           [error userInfo]);
        }


 return success;
 } 
- (void)mergeChanges:(NSNotification *)notification
{

    NSManagedObjectContext* moc = [self myManagedObjectContext];

    AppDelegate * delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *mainContext = [delegate mainThreadMOC];

    // Merge changes into the main context on the main thread
    [mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
                                  withObject:notification
                               waitUntilDone:YES];  

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 

    [nc removeObserver:self name:NSManagedObjectContextDidSaveNotification object:moc];
} 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    mainThreadMOC = [[NSManagedObjectContext alloc]init];
    [mainThreadMOC setMergePolicy: NSMergeByPropertyObjectTrumpMergePolicy];
    [mainThreadMOC setPersistentStoreCoordinator: [[DatabaseManager sharedManager] persistentStoreCoordinator]];



    [[DatabaseManager sharedManager] StoreManagedObjectContextForCurrentThread:mainThreadMOC];
.....
.....
}

キャッチされていない例外 'NSInvalidArgumentException' が原因でアプリを終了しています。理由: '-[NSKeyPathExpression _processReferenceQueue:]: 認識されないセレクターがインスタンス 0xa65940 に送信されました'

0   CoreFoundation                      0x3587a987 __exceptionPreprocess + 114
1   libobjc.A.dylib                     0x34a8249d objc_exception_throw + 24
2   CoreFoundation                      0x3587c133 -[NSObject(NSObject) doesNotRecognizeSelector:] + 102
3   CoreFoundation                      0x35823aa9 ___forwarding___ + 508
4   CoreFoundation                      0x35823860 _CF_forwarding_prep_0 + 48
5   CoreData                            0x356ea3d5 -[NSManagedObjectContext(_NSInternalNotificationHandling) _processReferenceQueue:] + 24
6   CoreData                            0x3573032b -[NSManagedObjectContext mergeChangesFromContextDidSaveNotification:] + 842
7   CoreFoundation                      0x35818bbf -[NSObject(NSObject) performSelector:withObject:] + 22
8   Foundation                          0x31181795 __NSThreadPerformPerform + 268
9   CoreFoundation                      0x358307dd __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 12
10  CoreFoundation                      0x358025b7 __CFRunLoopDoSources0 + 382
11  CoreFoundation                      0x35801e5b __CFRunLoopRun + 230
12  CoreFoundation                      0x35801c87 CFRunLoopRunSpecific + 230
13  CoreFoundation                      0x35801b8f CFRunLoopRunInMode + 58
14  GraphicsServices                    0x320c84ab GSEventRunModal + 114
15  GraphicsServices                    0x320c8557 GSEventRun + 62
16  UIKit                               0x341dc329 -[UIApplication _run] + 412
17  UIKit                               0x341d9e93 UIApplicationMain + 670
4

1 に答える 1

1

これが問題かどうかはわかりませんが、常に関数から autoreleased-values を返す必要があります。

あなたはやっている:

[moc release];      // now owned by the thread dictionary
return moc ;

ただし、スレッド辞書の所有権に関係なく、次のようにする必要があります。

return [moc autorelease];
于 2010-12-25T20:05:29.000 に答える