大家好我有一个在我的应用程序中使用sqlite数据库的类。在这里你可以看到我写的一个功能。此函数必须获取列值中的项目数等于给定值。
+ (int) GetCountOfItems: (NSString*) byColumn {
// Autorelease Pool.
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc]init];
// Create Sqlite query string.
NSString* sqliteQuery = [NSString stringWithFormat:@"SELECT COUNT(*) FROM [Articles] WHERE %@ = 1", byColumn];
NSLog(@"GetCountOfItems query string is: %@", sqliteQuery);
// Create statement.
sqlite3_stmt* stmt;
int articleCount = 0;
if( sqlite3_prepare_v2(database, [sqliteQuery UTF8String], -1, &stmt, NULL) == SQLITE_OK ) {
if( sqlite3_step(stmt) == SQLITE_ROW )
articleCount = sqlite3_column_int(stmt, 0);
}
else NSLog(@"Failed from GetCountOfItems. Error is: %c", sqlite3_errmsg(database));
// Finalize.
sqlite3_finalize(stmt);
// Release Pool.
[pool release];
return articleCount;
}
我想知道这个函数是否正确,例如我应该使用NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; ???? 它如何帮助我记忆?
答案 0 :(得分:3)
如果在主线程中执行此代码,则不需要。
如果这是在另一个线程中执行,那么,是的,你必须。
答案 1 :(得分:2)
基于以下描述(在Memory Management Programming Guide中):
Application Kit会在事件周期(或事件循环迭代)开始时自动创建一个池,例如鼠标按下事件,并在结束时将其耗尽,因此您的代码通常不必担心它们。但是,有三种情况可以使用您自己的自动释放池:
如果您正在编写一个不基于Application Kit的程序,例如命令行工具,则不存在对自动释放池的内置支持;你必须自己创造它们。
如果生成辅助线程,则必须在线程开始执行后立即创建自己的自动释放池;否则,你会泄漏物体。 (有关详细信息,请参阅“自动释放池和线程”。)
如果编写一个创建许多临时对象的循环,则可以在循环内创建一个自动释放池,以便在下一次迭代之前处理这些对象。这有助于减少应用程序的最大内存占用量。
我想说不要打扰,只需根据需要分配任何对象,然后在从方法返回之前释放它们。
另请参阅此post。
答案 2 :(得分:1)
通常,我只需要在创建线程时使用自动释放池。
您需要添加sqlite3_mprintf和sqlite3_free语句。
+ (int) GetCountOfItems: (NSString*) byColumn {
NSString* sqliteQuery = @"SELECT COUNT(*) FROM [Articles] WHERE %q = 1";
char *sql = sqlite3_mprintf((char*)[sqliteQuery UTF8String], (char*)[byColumn UTF8String]); //Add this statement
sqlite3_stmt* stmt;
int articleCount = 0;
if( sqlite3_prepare_v2(database, sql, -1, &stmt, NULL) == SQLITE_OK ) {
if( sqlite3_step(stmt) == SQLITE_ROW )
articleCount = sqlite3_column_int(stmt, 0);
}
else NSLog(@"Failed from GetCountOfItems. Error is: %c", sqlite3_errmsg(database));
sqlite3_finalize(stmt);
sqlite3_free(sql); //Add this statement
return articleCount;
}
答案 3 :(得分:0)
NSAutoreleasePool类用于支持Cocoa的引用计数内存管理系统。自动释放池存储在池本身耗尽时发送释放消息的对象。
在引用计数环境中(与使用垃圾收集的环境相反),NSAutoreleasePool对象包含已收到自动释放消息的对象,并且在排空时,它会向每个对象发送释放消息。因此,发送自动释放而不是释放到对象会延长该对象的生命周期,至少直到池本身耗尽(如果随后保留该对象,则可能更长)。一个对象可以多次放入同一个池中,在这种情况下,每次将它放入池中时都会收到一条释放消息。
在引用计数环境中,Cocoa期望有一个始终可用的自动释放池。如果池不可用,则自动释放的对象不会被释放并且您会泄漏内存。在这种情况下,您的程序通常会记录适当的警告消息。
Application Kit在事件循环的每个循环开始时在主线程上创建一个自动释放池,并在最后将其排出,从而释放处理事件时生成的任何自动释放的对象。如果您使用Application Kit,则通常不必创建自己的池。但是,如果您的应用程序在事件循环中创建了许多临时自动释放的对象,那么创建“本地”自动释放池以帮助最小化峰值内存占用量可能是有益的。
使用通常的alloc和init消息创建一个NSAutoreleasePool对象,并使用drain(或release)来处理它以了解其中的差异,请参阅“垃圾收集”。由于您无法保留自动释放池(或自动释放它 - 请参阅保留和自动释放),因此耗尽池最终会释放它。您应该始终在创建它的相同上下文(调用方法或函数或循环体)中排出自动释放池。有关详细信息,请参阅自动释放池。
每个线程(包括主线程)都维护自己的NSAutoreleasePool对象堆栈(请参阅“线程”)。在创建新池时,它们会添加到堆栈顶部。当池被释放时,它们将从堆栈中删除。自动释放的对象放置在当前线程的顶部自动释放池中。当一个线程终止时,它会自动排出与自身相关的所有自动释放池。