gpt4 book ai didi

objective-c - ARC 和重用指针会耗尽内存

转载 作者:行者123 更新时间:2023-11-28 19:21:35 25 4
gpt4 key购买 nike

我认为在 ARC 实现之前我一直在考虑保留和释放,我倾向于尝试重用指针以避免一直重新声明它们。

但是对于 ARC,它会造成泄漏。我的猜测是它只是释放分配给“tmp”指针的最后一个对象,我假设当我给一个指针一个新对象时,旧对象会自动释放。将函数包装在 autoreleasepool 中似乎可以完成这项工作,但这真的是理想的解决方案还是我的编码风格有误?

这是一个有罪的函数,在我运行它几百次之后似乎把我所有的 ram 都吃光了:

- (void) saveJDictEntry:(JDictEntry *)entry {

const char * query;
char * errMsg;
NSString *queryString;
sqlite3_stmt * statement;

[self connect];

// Insert the word..
queryString = [NSString stringWithFormat:@"INSERT INTO words (seq) VALUES (%i)", entry.number];
query = [queryString UTF8String];
if (sqlite3_exec(database, query, NULL, NULL, &errMsg) != SQLITE_OK) {
NSLog(@"Statement failed %@ %@", errMsg, queryString);
}


// Get the last id we inserted..
NSUInteger lastId = 0;
queryString = @"SELECT last_insert_rowid()";
query = [queryString UTF8String];
sqlite3_prepare_v2(database, query, -1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_ROW) {
lastId = sqlite3_column_int(statement, 0);
} else {
NSLog(@"Failed to fetch last Id after saving");
}
sqlite3_finalize(statement);

entry.databaseId = lastId;
entry.saved = true;



// Kana...
queryString = [NSString stringWithFormat:@"INSERT INTO words_kana (word_id, kana) VALUES (%i, '%@')", entry.databaseId, entry.kana ];
query = [queryString UTF8String];
if (sqlite3_exec(database, query, NULL, NULL, &errMsg) != SQLITE_OK) {
NSLog(@"Statement failed %@ %@", errMsg, queryString);
}

// Kanji ...
for(NSString * _kanji in entry.kanji) {
queryString = [NSString stringWithFormat:@"INSERT INTO words_kanji (word_id, kanji) VALUES (%i, '%@')", entry.databaseId, _kanji];
query = [queryString UTF8String];
if (sqlite3_exec(database, query, NULL, NULL, &errMsg) != SQLITE_OK) {
NSLog(@"Statement failed %@ %@", errMsg, queryString);
}
}

// Pos..
for(NSString * _pos in entry.pos) {
queryString = [NSString stringWithFormat:@"INSERT INTO words_pos (word_id, pos) VALUES (%i, '%@')", entry.databaseId, _pos];
query = [queryString UTF8String];
if (sqlite3_exec(database, query, NULL, NULL, &errMsg) != SQLITE_OK) {
NSLog(@"Statement failed %@ %@", errMsg, queryString);
}
}

// Gloss
for(NSString * _gloss in entry.gloss) {
NSString * glossField = [_gloss stringByReplacingOccurrencesOfString:@"'" withString:@"''"];
queryString = [NSString stringWithFormat:@"INSERT INTO words_gloss (word_id, gloss) VALUES (%i, '%@')", entry.databaseId, glossField];
query = [queryString UTF8String];
if (sqlite3_exec(database, query, NULL, NULL, &errMsg) != SQLITE_OK) {
NSLog(@"Statement failed %@ %@", errMsg, queryString);
}
}


}

最佳答案

旧的内存管理概念仍然适用,全局释放池中的自动释放实例在完成当前运行循环之前不会被释放,有或没有 ARC。

如果您正在编写非平凡的迭代,例如数千次迭代,用自动释放池包装它是可行的方法。你可能会使用

@autoreleasepool {
// your code here
}

为了简化使用。使用自动释放池并没有错或不理想,因为出于某种原因它一直在那里。 ARC,顾名思义,只做自动引用计数。管理内存使用的任务仍然属于我们。

关于objective-c - ARC 和重用指针会耗尽内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8535663/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com