后台线程的行为方式不同,具体取决于调用方法的时间

时间:2012-06-28 19:18:28

标签: ios multithreading core-data uisearchbar nsfetchedresultscontroller

在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时调用的方法调用它时(fetch在输入时动态显示获取的结果)在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内容,但是我无法看到错误的位置。

任何指针?提前谢谢!

1 个答案:

答案 0 :(得分:1)

我认为这可能是因为访问搜索栏的文字造成的。我在我的一个后台线程方法上发出了类似的警告,我将问题跟踪到搜索栏的文本方法。我注意到你也在这样做。

如果是这种情况,警告的一个简单解决方案就是在仍然在主线程上时获取搜索栏的文本。

它确实解决了我的问题,但我真的想知道警告出现的原因。我一直试图在网络和Apple的文档中找到一些关于这一点的东西,但是还没有运气。