【问题标题】:Crashing application due to secondary thread trying to update UI由于辅助线程尝试更新 UI 而导致应用程序崩溃
【发布时间】:2011-05-05 07:02:21
【问题描述】:

我正在使用搜索栏从 Sqlite DB 填充的表中选择记录。 每 120 条记录更新表,每 200 条记录重新加载表。 当我将表格拖动到限制时,我的应用程序崩溃了。当某个限制被覆盖时它崩溃并出现错误“辅助线程试图更新 UI”。这里是代码

 if (indexPath.row > limit)
    {
        llimit = llimit+200 ;
        ulimit = ulimit+200 ;
           NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        [opq cancelAllOperations];
        NSLog(@"before ns operation");
        opq = [NSOperationQueue new];
        NSInvocationOperation *op = [[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(searchData) object:nil] autorelease];
        [opq addOperation:op];
        [pool drain];
        i++;
        limit = limit + 120 ;
    }



- (void) searchData {

    NSString *databaseName = @"imeating.sql";
    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
    NSString *documentsDir=[documentPaths objectAtIndex:0];
    NSString *databasePath=[documentsDir stringByAppendingPathComponent:databaseName];
    sqlite3 *database;

    if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK)
    {
        // Setup the SQL Statement and compile it for faster access
        sqlite3_stmt *compiledStatement ;
        const char *sqlStatement ;

        sqlStatement = "select category_id, upper(subitem_name), subitem_detail_id from subitem_detail where subitem_name LIKE ? order by subitem_name limit ?,?" ;
       NSLog(@"inside search b4 wildsearch %@",searchString);

        wildSearch = [NSString stringWithFormat:@"%@%@",searchString, @"%"];



        if (sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) 
        {

            sqlite3_bind_text(compiledStatement, 1, [wildSearch UTF8String], -1, SQLITE_TRANSIENT);
            sqlite3_bind_int(compiledStatement, 2, llimit);
            sqlite3_bind_int(compiledStatement, 3, ulimit);

            if (llimit <200){
                 NSLog(@"with in if limit < 200");

                itemArray = [[NSMutableArray alloc] init] ;
            }

            while (sqlite3_step(compiledStatement) == SQLITE_ROW) {


                NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init] ;

                NSString *categoryId = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
                NSString *itemName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
                NSString *itemId = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];

                if (ulimit%200 == 0)
                {

                    [newTableView reloadData];


                }
                [pool drain];
            } 


        }
    }

这种情况发生在设备中,而不是在模拟器中,延迟加载也发生在表视图中。我正在使用 sqllite DB(包含大量数据)来填充表。 我可以在应用程序崩溃后将表格拖到一定范围内。崩溃限制不是恒定的。请帮助我以完美的方式实现这一点

提前致谢

【问题讨论】:

  • 请给出答案...我已经纠正了以下答案...但是现在正在发生延迟加载表格...我喜欢在表格中使用显示更多选项...就像应用商店工作......我怎么能把它放在我的桌子上......从sqlite DB加载时
  • 您的应用程序如何崩溃?错误信息是什么?您的 SQL 查询返回了多少结果?
  • 它显示辅助线程试图更新 UI...我的 sqlite 中有大量数据。

标签: objective-c multithreading crash thread-safety


【解决方案1】:

您不能在辅助线程中更新 UI,如果您需要更新 UI,请使用 -

[self performSelectorOnMainThread:@selector() withObject:nil waitUntilDone:YES];

【讨论】:

  • 对不起,我可以在哪里粘贴上面的代码? NSInvocationOperation *op = [[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(searchData) object:nil] autorelease];错了吗?
  • 替换这个 NSInvocationOperation *op = [[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(searchData) object:nil] autorelease]; with [self performSelectorOnMainThread:@selector(searchData) withObject:nil waitUntilDone:YES];
  • 所以它将 NSInvocationOperation *op = [[[NSInvocationOperation alloc] initWithTarget:self performSelectorOnMainThread:@selector() withObject:nil waitUntilDone:YES];是这样吗?
  • no 不要使用 NSInvocationOperation 它是辅助线程,直接使用 [self performSelectorOnMainThread:@selector(searchData) withObject:nil waitUntilDone:YES];
  • f (indexPath.row > limit) { llimit = llimit+200 ; ulimit = ulimit+200 ; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; [opq 取消所有操作]; opq = [NSOperationQueue 新]; [self performSelectorOnMainThread:@selector(searchData) withObject:nil waitUntilDone:YES]; [opq addOperation:op] [pool drain];..这是正确的吗?对不起,我是 iphone 开发的初学者
猜你喜欢
  • 2012-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-17
  • 2016-08-05
相关资源
最近更新 更多