viewDidLoad 方法中的 iOS 慢速 SQL 查询



我有一个基于导航控制器的聊天应用程序。

在显示对话的视图中,我在 viewDidLoad 方法中从 SQLite 加载所有以前的历史记录。

当对话增长时,需要几秒钟才能打开视图,因此感觉"滞后"。

下面是我用来从数据库加载历史记录的代码。

有什么想法可以改进以使UI感觉更灵敏吗?

NSString *sql = [NSString stringWithFormat:@"SELECT * FROM chatHistory WHERE channelID = '%@' ORDER BY time ASC", box.activeChannel];
sqlite3_stmt *statement;
if(sqlite3_prepare_v2([box db], [sql UTF8String], -1, &statement, nil) == SQLITE_OK) {
    while(sqlite3_step(statement) == SQLITE_ROW) {
        char *field1 = (char *) sqlite3_column_text(statement, 0);
        NSString *channelID = [[NSString alloc] initWithUTF8String:field1];
        char *field2 = (char *) sqlite3_column_text(statement, 1);
        NSString *sender = [[NSString alloc] initWithUTF8String:field2];
        char *field3 = (char *) sqlite3_column_text(statement, 2);
        NSString *message = [[NSString alloc] initWithUTF8String:field3];
        char *field4 = (char *) sqlite3_column_text(statement, 3);
        NSString *recipient = [[NSString alloc] initWithUTF8String:field4];
        char *field5 = (char *) sqlite3_column_text(statement, 4);
        NSString *time = [[NSString alloc] initWithUTF8String:field5];
        NSString *str = [[NSString alloc] initWithFormat:@"%@", message];
        NSString *str1 = [[NSString alloc] initWithFormat:@"%@", channelID];
        NSString *str2 = [[NSString alloc] initWithFormat:@"%@", sender];
        NSString *str3 = [[NSString alloc] initWithFormat:@"%@", time];

        NSString *trimmedStr2 = [str2 stringByTrimmingCharactersInSet:
                                 [NSCharacterSet whitespaceCharacterSet]];
        NSString *trimmedAgentName = [box.agentName stringByTrimmingCharactersInSet:
                                      [NSCharacterSet whitespaceCharacterSet]];
        NSString *trimmedTime = [str3 stringByTrimmingCharactersInSet:
                                 [NSCharacterSet whitespaceCharacterSet]];

        NSDateFormatter *df = [[NSDateFormatter alloc] init];
        [df setDateFormat:@"yyyy-MM-dd HH:mm:ss ZZZ"];
        NSDate *myDate = [df dateFromString:trimmedTime];

        if ([trimmedStr2 isEqualToString:trimmedAgentName]) {
            [self.messages addObject:[[JSMessage alloc] initWithText:str sender:trimmedAgentName date:myDate]];
            [self finishSend];
            [self scrollToBottomAnimated:YES];
        } else {
            [self.messages addObject:[[JSMessage alloc] initWithText:str sender:kSubtitleVisitor date:myDate]];
            [self finishSend];
            [self scrollToBottomAnimated:YES];
        }
    }
}

编辑

我还尝试将代码放在dispatch_queue中,这使得切换到视图的速度要快得多,但是添加消息时仍然滞后。

您可以在代码中优化一些地方:

  • 无需创建str str1 str2 str3,只需使用message channelID sender time即可。
  • NSDateFormatter创建范围很广,则应在 while 循环之外创建一个实例。
  • viewDidLoad UI 线程中调用,查询将需要很长时间才能执行和阻止 UI,你可能希望在后台执行 SQL 查询。请参阅 Apple 的并发编程指南了解更多信息。

最新更新