繁体   English   中英

在Objective C中为NSMutableArray对象使用指针

[英]Using pointers in Objective C for NSMutableArray objects

在可可触摸中从NSMutableArray检索对象时,以下代码可以吗? 我应该每次分配([alloc])新的Page对象,还是只是指向它? 之后,是否需要对Page * pageObj做任何事情,例如将其设置为nil?

const char *sql = "insert into Page(Book_ID, Page_Num, Page_Text) Values(?, ?, ?)";
for (i = 0; i < ([[self pagesArray] count] - 1); i++) {
    if(addStmt == nil) {
        if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK) {
            NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg(database));
        }
    }
    Page *pageObj = [[self pagesArray] objectAtIndex:i];
    if(pageObj.isNew) {
        sqlite3_bind_int(addStmt, 1, self.book_ID); 
        sqlite3_bind_int(addStmt, 2, pageObj.page_Number);  
        sqlite3_bind_text(addStmt, 3, [[pageObj page_Text] UTF8String], -1, SQLITE_TRANSIENT);
        if(SQLITE_DONE != sqlite3_step(addStmt)) {
            NSAssert1(0, @"Error while inserting data. '%s'", sqlite3_errmsg(database));
        }
        NSLog(@"Inserted Page: %i into DB. Page text: %@", pageObj.page_Number, pageObj.page_Text);
    }
    //Reset the add statement.
    sqlite3_reset(addStmt);                     
}

谢谢。 我也知道这可能应该在交易中,但我还没有完全解决这个问题。

您声明指针的方式是正确的。 当您要引用数组中的现有对象时,不需要alloc,因为这会创建一个新对象。 如果要将引用保留在该方法之外,则希望保留它,但是由于您只是临时使用它,所以最好不要使用它。

实际的指针变量将在每次循环时被销毁并重新创建,因此无需将其设置为nil。 即使您在循环外声明了变量,只需将其分配给新对象也可以。 唯一将其设置为nil的情况是释放存储在指针中的对象(或者该对象可能在其他地方释放)。 如果在这种情况下未将其设置为nil,则指针在分配对象后将指向无效的内存位置,通常会导致崩溃。

我可以看到一个错误,您通过从计数中减去1来跳过for循环中数组中的最后一个元素。

除了前面提到的计数错误外,它看起来还不错。

就事务而言,我强烈建议将此写循环包装为一个。 这将大大提高您的写入性能,我发现它也有助于内存使用。 我使用以下类方法开始事务:

+ (BOOL)beginTransactionWithDatabase:(sqlite3 *)database;
{
    const char *sql1 = "BEGIN EXCLUSIVE TRANSACTION";
    sqlite3_stmt *begin_statement;
    if (sqlite3_prepare_v2(database, sql1, -1, &begin_statement, NULL) != SQLITE_OK)
    {
        return NO;
    }
    if (sqlite3_step(begin_statement) != SQLITE_DONE) 
    {
        return NO;
    }
    sqlite3_finalize(begin_statement);
    return YES;
}

而这个结束交易:

+ (BOOL)endTransactionWithDatabase:(sqlite3 *)database;
{
    const char *sql2 = "COMMIT TRANSACTION";
    sqlite3_stmt *commit_statement;
    if (sqlite3_prepare_v2(database, sql2, -1, &commit_statement, NULL) != SQLITE_OK)
    {
        return NO;
    }
    if (sqlite3_step(commit_statement) != SQLITE_DONE) 
    {
        return NO;
    }
    sqlite3_finalize(commit_statement);
    return YES;
}

我可能应该存储SQL语句以供以后重用,但是与我的其他查询相比,这些事务语句的调用频率要低得多。

当然不是。 您之前已经分配了它,只是在引用同一对象。 无需重新分配。 另外,您无需将其设置为nil。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM