1

我正在制作一个 ios 应用程序,它通过网络获取 xml 提要,解析并将其存储在 sqlite db 中,然后显示给用户。

我的 xml 提要大约有 1700 行长: http: //www.paulshin.ca/yunatube/res/en.xml

这就是我的应用程序应该如何工作的方式。

  1. 用户运行应用程序
  2. 应用通过网络获取 xml
  3. 使用 xml 解析器并循环遍历 xml 对象并将每个项目存储在 sqlite db
  4. 完成后,在表格视图中显示项目..

但是,我发现第 2 步需要不到 5 秒,而第 3 步需要大约 20 秒。原因是因为将每个项目存储到数据库中需要一些时间。

以下是我用于第 3 步的内容。

TBXMLElement *elemRoot = nil, *youtube = nil, *maincateg = nil, *categ = nil, *clip = nil;

    // maincatg
    NSString *mcTitle = nil;
    // catge
    NSString *cTitle = nil;
    // clip
    NSString *title = nil, *url = nil, *note = nil;

    elemRoot = tbxml.rootXMLElement;

    if (elemRoot) {
        youtube = [TBXML childElementNamed:@"youtube" parentElement:elemRoot];
        maincateg = [TBXML childElementNamed:@"maincateg" parentElement:youtube];

        while (maincateg) {
            mcTitle = [TBXML valueOfAttributeNamed:@"type" forElement:maincateg];

            categ = [TBXML childElementNamed:@"category" parentElement:maincateg];
            while (categ) {
                cTitle = [TBXML valueOfAttributeNamed:@"title" forElement:categ];

                clip = [TBXML childElementNamed:@"clip" parentElement:categ];
                while (clip) {
                    title = [TBXML valueOfAttributeNamed:@"title" forElement:clip];
                    url = [TBXML valueOfAttributeNamed:@"url" forElement:clip];
                    note = [TBXML valueOfAttributeNamed:@"note" forElement:clip];

                    //TODO
                    if (![note isEqualToString:@"0"]) {
                        // save pared data to persistent

                        title = [title stringByReplacingOccurrencesOfString:@"&"
                                                                 withString:@"&"];
                        cTitle = [cTitle stringByReplacingOccurrencesOfString:@"&"
                                                                 withString:@"&"];

                        DatabaseManager *database = [DatabaseManager getInstance];
                        **[database addDataToTable:mcTitle title:title url:url category:cTitle];**
                    }
                    clip = clip -> nextSibling;
                }
                categ = categ -> nextSibling;
            }

            maincateg = maincateg -> nextSibling;
        }

如您所见,我有一些嵌套循环,我通过调用 addDataToTAble(); 将每个项目存储到数据库中。如果我删除带有 * 的行(换句话说,如果我在每个循环后不存储项目),它的工作速度非常快。但是,如果我将 * 保留原样,则需要很长时间。

这个函数如下:

-(void) addDataToTable: (NSString*)table
             title: (NSString*)title
               url:(NSString*)url
          category:(NSString*)category
{
    sqlite3_stmt *statement;
    const char *dbpath = [_databasePath UTF8String];

    if (sqlite3_open(dbpath, &_yunatubeDB) == SQLITE_OK) {

        NSString *insertSQL = [NSString stringWithFormat: @"INSERT INTO %@ (TITLE, URL, CATEGORY) VALUES (\"%@\", \"%@\", \"%@\")", table, title, url, category];

        const char *insert_stmt = [insertSQL UTF8String];
        sqlite3_prepare_v2(_yunatubeDB, insert_stmt,
                           -1, &statement, NULL);
        if (sqlite3_step(statement) == SQLITE_DONE) {
            //            NSLog(@"Successfully added to DB");
        } else {
            NSLog(@"Failed to add data to DB");
        }
        sqlite3_finalize(statement);
        sqlite3_close(_yunatubeDB);
    }
}

这个功能在存储每个项目时似乎需要一段时间,并且由于存储时间累积,最终需要长达 20 秒。我对 android 使用了类似的算法,它运行得很快,但我不知道为什么在 ios 上需要这么长时间。我想知道这个处理时间是否会对应用商店中的应用评论产生负面影响。我在 android 上使用了类似的方法,它在那里工作得非常快.. 不到 4 秒。我不知道为什么在ios上需要这么长时间。难道我做错了什么 ?

任何帮助表示赞赏!

4

2 回答 2

1

尝试在循环之前启动 SQLite 事务并在之后结束它。如果您不手动启动/停止事务,SQLite 会在每次写入时自动执行,这非常慢。

于 2013-06-23T06:36:42.783 回答
0

20 秒可能会通过苹果审核,但永远不会让您的应用获得好评。

每次找到条目时,您都会写信给 db。您应该在解析结束时写入 db。

于 2013-06-23T06:37:23.583 回答