0

CoreDataTableViewController (スタンフォードの人々によって作成されたサブクラス) で、sqlite データベースからのフェッチがあります。

フェッチはシミュレーターとデバイスで非常に高速ですが、古いデバイスに適したものにするために、バックグラウンドでフェッチを実行し、実行中にスピナーを追加したいと考えています。そこで、プリフェッチ メソッドを追加しました。全体は次のようになります。

-(void)setupFetchedResultsController{

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:self.entity];

    request.propertiesToFetch=[NSArray arrayWithObject:self.attribute];
    request.resultType=NSDictionaryResultType;
    request.returnsDistinctResults=YES;

    NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"%K != nil", self.attribute]; 
    NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"%K != ''", self.attribute];
    NSPredicate *predicate3=  [NSPredicate predicateWithFormat:@"%K contains[cd] %@", self.attribute, self.seachBar.text];

    NSArray *prepredicateArray;

    if ([self.seachBar.text length]) {
         prepredicateArray = [NSArray arrayWithObjects:predicate1, predicate2, predicate3,nil];

    }else {
         prepredicateArray = [NSArray arrayWithObjects:predicate1, predicate2,nil];

    }

    request.predicate=[NSCompoundPredicate andPredicateWithSubpredicates:prepredicateArray];
    request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:self.attribute ascending:YES ]];


    self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                                        managedObjectContext:self.managedObjectContext
                                                                          sectionNameKeyPath:nil
                                                                                   cacheName:nil];


    [self performFetch];
}





-(void)prefetch{

    UIView *translucentView=[[UIView alloc]initWithFrame:CGRectMake(110, 102, 100, 100)];
    [translucentView setCornerRadius:7.0];
    translucentView.backgroundColor=[UIColor blackColor];
    translucentView.alpha=0.65;

    UIActivityIndicatorView *spinner=[[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    spinner.frame=CGRectMake(0, 31.5, 100, 37);
    [translucentView addSubview:spinner];

    [spinner startAnimating];

    [self.view addSubview:translucentView];


    dispatch_queue_t fetchQueue = dispatch_queue_create("fetch stuff", NULL);

    dispatch_async(fetchQueue, ^{

        [self setupFetchedResultsController];

        dispatch_async(dispatch_get_main_queue(), ^{

            [translucentView removeFromSuperview];

        });

    });

    dispatch_release(fetchQueue);

}

prefetch問題は、すべてからメソッドを呼び出すviewWillAppearときは問題ありませんが、searchBar の編集時に呼び出されるメソッドから呼び出すと (searchBar で入力しているときにフェッチによってフェッチされた結果が動的に表示される)、次のエラーが発生することです。

void _WebThreadLockFromAnyThread(bool), 0x6b9b730: Obtaining the web lock from a thread other than the main thread or the web thread. UIKit should not be called from a secondary thread.

メイン スレッドで UI を実行する必要があることは理解していましたが、エラーの場所がわかりません。

ポインタはありますか?前もって感謝します!

4

1 に答える 1

1

検索バーのテキストにアクセスしたことが原因である可能性があると思います。バックグラウンド スレッド メソッドの 1 つで同様の警告が発生し、検索バーのテキスト メソッドまで問題を追跡しました。あなたもそうしていることに気づきました。

このような場合、警告の簡単な解決策は、メイン スレッドにいる間に検索バーのテキストを取得することです。

問題は解決しますが、警告が表示される理由を本当に知りたいです。しばらくの間、Web と Apple のドキュメントの両方でこれについて何かを見つけようとしてきましたが、まだ運がありません。

于 2012-08-01T19:31:08.417 に答える