0

これまでのところ、これは私が試したものです:

+(NSManagedObject *) getObjectWithStringOfValue:(NSString *) Value fromTable:(NSString*) table withAttribut:(NSString *) AttributName
{
    NSManagedObject * buffer=nil;
    @synchronized(self)
    {
        buffer=[self LookUpObjectWithAttributeValue:Value fromTable:table WithAttribut:AttributName];
        if (buffer == nil)
        {
            //CLog( @"gk boleh create");
            buffer=[self CreateNewObjectFromTable:table];
            [buffer setValue:Value forKey:AttributName];
            [BGMDCRManagedObjectContextThreadHandler commit];
            NSAssert([self LookUpObjectWithAttributeValue:Value fromTable:table WithAttribut:AttributName], @"Object must exist and must only be one");
        }
        else
        {
            //assert(!(buffer.isFault));
        }
    }


    return buffer;
}

基本的に@synchronizedが必要です。1つのスレッドがオブジェクトの作成がないことを確認し、別のスレッドが同じことを実行し、両方が代わりに2つのオブジェクトをコミットする可能性があります。

ただし、これによりデッドロックが発生することがよくあります。

私の実装では、すべてのスレッドに独自のmocがあります。したがって、[BGMDCRManagedObjectContextThreadHandlermanagedobjectcontext]はそのスレッドにmocを与えます。すべてのmocには同じ親があり、メインスレッドで作成されたメインの管理対象オブジェクトコンテキストです。

LookUpObjectWithAttributeValue内のexecuteFetchRequestが停止すると、ロックが発生します。一方、メインスレッドも@synchronized(self)で停止します。

これをどうやって直すのかしら?

メインのmanagedObjectContextがメインスレッドに関連付けられていないことを確認する必要がありますか?

4

1 に答える 1

0

コアデータに直接アクセスすることはめったにありません。したがって、たとえば、excecuteFetchRequestを実行するコードはプログラム全体で1行だけです。

私は子供が親に間接的にアクセスするたびにBlockAndWaitを実行します

[moc performBlockAndWait:^{
    saveSuccesfully = [moc save:&error];
    if (!saveSuccesfully) {
        CLog(@"Error in Saving %@", error);
    }
    else{
    }
}];

[moc performBlockAndWait:^{
    fetchedObjects = [moc executeFetchRequest:request error:&error];
}];

    [moc performBlock:^{
        if (![moc save:&error])
        {
            CLog(@"Error in Saving %@", error);// handle error
        }
    }];

それ以来、再びデッドロックは発生しません。

于 2013-01-28T05:09:54.633 に答える