簡體   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