我应该使用 AutoreleasePool 吗?

发布于 2024-10-30 23:46:04 字数 1146 浏览 2 评论 0原文

大家好,我的应用程序中有一个与 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]; ????它如何帮助我提高记忆力?

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 ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

彼岸花ソ最美的依靠 2024-11-06 23:46:04

如果此代码在主线程中执行,那么,不,您不必这样做。

如果这是在另一个线程中执行的,那么,是的,你必须这样做。

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.

双马尾 2024-11-06 23:46:04

基于以下描述(在 内存管理编程指南):

应用程序工具包会在事件周期(或事件循环迭代)开始时自动创建一个池,例如鼠标按下事件,并在结束时耗尽它,因此您的代码通常不必担心它们。不过,在三种情况下,您可以使用自己的自动释放池:

如果您正在编写不基于Application Kit的程序,例如命令行工具,则没有对自动释放池的内置支持;您必须自己创建它们。

如果生成辅助线程,则必须在线程开始执行后立即创建自己的自动释放池;否则,你会泄漏对象。 (有关详细信息,请参阅“自动释放池和线程”。)

如果您编写一个创建许多临时对象的循环,则可以在循环内创建一个自动释放池,以便在下一次迭代之前处理这些对象。这有助于减少应用程序的最大内存占用。

我想说不要打扰,只需根据需要分配任何对象,然后在从方法返回之前释放它们。

另请参阅此帖子

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.

血之狂魔 2024-11-06 23:46:04

一般来说,我只需要在创建线程时使用自动释放池。

您需要添加 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;
    }

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;
    }
看透却不说透 2024-11-06 23:46:04

NSAutoreleasePool 类用于支持 Cocoa 的引用计数内存管理系统。自动释放池存储在池本身耗尽时发送释放消息的对象。

在引用计数环境中(与使用垃圾收集的环境相反), NSAutoreleasePool 对象包含已接收自动释放消息的对象,并且在耗尽时向每个对象发送释放消息。因此,向对象发送 autorelease 而不是 release 会延长该对象的生命周期,至少直到池本身耗尽为止(如果随后保留该对象,则可能会更长)。一个对象可以多次放入同一个池中,在这种情况下,每次将其放入池中时,它都会收到一条释放消息。

在引用计数环境中,Cocoa 期望有一个始终可用的自动释放池。如果池不可用,则自动释放的对象不会被释放,并且会泄漏内存。在这种情况下,您的程序通常会记录适当的警告消息。

应用程序工具包在事件循环的每个周期开始时在主线程上创建一个自动释放池,并在结束时耗尽它,从而释放在处理事件时生成的任何自动释放对象。如果您使用应用程序工具包,那么您通常不必创建自己的池。然而,如果您的应用程序在事件循环中创建了大量临时自动释放对象,则创建“本地”自动释放池可能会有所帮助,以帮助最大限度地减少峰值内存占用。

您可以使用通常的 alloc 和 init 消息创建一个 NSAutoreleasePool 对象,并使用排出(或释放 - 要了解差异,请参阅“垃圾收集”)来处理它。由于您无法保留自动释放池(或自动释放它 - 请参阅保留和自动释放),因此耗尽池最终会产生释放它的效果。您应该始终在创建它的同一上下文(方法或函数的调用,或循环体)中耗尽自动释放池。有关更多详细信息,请参阅自动释放池。

每个线程(包括主线程)维护自己的 NSAutoreleasePool 对象堆栈(请参阅“线程”)。创建新池时,它们会被添加到堆栈的顶部。当池被释放时,它们将从堆栈中删除。自动释放的对象被放置到当前线程的顶部自动释放池中。当线程终止时,它会自动耗尽与其自身关联的所有自动释放池。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文