Hi All I have a class that works with sqlite database in my application. Here you can see one of the functions that I have write. This function must get the count of items in witch the column value is equals to the given value.
+ (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;
}
I want to know if this function is correct for example should i use NSAutoreleasePool* pool = [[NSAutoreleasePool alloc]init]; ???? And how it can help me with memory ?
If this code is executed in the main thread then, no, you don't have to.
If this is executed in another thread then, yes, you must.
Based on the following description (in the Memory Management Programming Guide):
The Application Kit automatically creates a pool at the beginning of an event cycle (or event-loop iteration), such as a mouse down event, and drains it at the end, so your code normally does not have to worry about them. There are three cases, though, where you might use your own autorelease pools:
If you are writing a program that is not based on the Application Kit, such as a command-line tool, there is no built-in support for autorelease pools; you must create them yourself.
If you spawn a secondary thread, you must create your own autorelease pool as soon as the thread begins executing; otherwise, you will leak objects. (See “Autorelease Pools and Threads” for details.)
If you write a loop that creates many temporary objects, you may create an autorelease pool inside the loop to dispose of those objects before the next iteration. This can help reduce the maximum memory footprint of the application.
I'd say don't bother, just allocate any objects as required, then release them before returning from the method.
Also, see this post.
Generally, I only need to use autorelease pools when I'm creating threads.
You need to add the sqlite3_mprintf and sqlite3_free statement.
+ (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;
}
The NSAutoreleasePool class is used to support Cocoa’s reference-counted memory management system. An autorelease pool stores objects that are sent a release message when the pool itself is drained.
In a reference-counted environment (as opposed to one which uses garbage collection), an NSAutoreleasePool object contains objects that have received an autorelease message and when drained it sends a release message to each of those objects. Thus, sending autorelease instead of release to an object extends the lifetime of that object at least until the pool itself is drained (it may be longer if the object is subsequently retained). An object can be put into the same pool several times, in which case it receives a release message for each time it was put into the pool.
In a reference counted environment, Cocoa expects there to be an autorelease pool always available. If a pool is not available, autoreleased objects do not get released and you leak memory. In this situation, your program will typically log suitable warning messages.
The Application Kit creates an autorelease pool on the main thread at the beginning of every cycle of the event loop, and drains it at the end, thereby releasing any autoreleased objects generated while processing an event. If you use the Application Kit, you therefore typically don’t have to create your own pools. If your application creates a lot of temporary autoreleased objects within the event loop, however, it may be beneficial to create “local” autorelease pools to help to minimize the peak memory footprint.
You create an NSAutoreleasePool object with the usual alloc and init messages and dispose of it with drain (or release—to understand the difference, see “Garbage Collection”). Since you cannot retain an autorelease pool (or autorelease it—see retain and autorelease), draining a pool ultimately has the effect of deallocating it. You should always drain an autorelease pool in the same context (invocation of a method or function, or body of a loop) that it was created. See Autorelease Pools for more details.
Each thread (including the main thread) maintains its own stack of NSAutoreleasePool objects (see “Threads”). As new pools are created, they get added to the top of the stack. When pools are deallocated, they are removed from the stack. Autoreleased objects are placed into the top autorelease pool for the current thread. When a thread terminates, it automatically drains all of the autorelease pools associated with itself.
精彩评论