如何正确使用 nsoperationqueue 的 autoreleasepool
我有一个正在重构的应用程序,我刚刚实现了多线程,以便 UI 可以运行得更流畅。在 iPhone 模拟器中,我没有遇到任何泄漏,但在运行 iOS 4.2 的 iPhone 3G 上进行测试时,出现了内存泄漏。我已经做了很多搜索来使用操作队列实现自动释放池的正确方法,我们将非常感谢您的帮助。
我在我的视图控制器中创建了一个 nsoperationqueue
- (void)loadData
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSOperationQueue *queue = [NSOperationQueue new]; // creates multithread for loading data without slowing UI
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(firstRun) object:nil];
[queue addOperation:operation];
[operation release];
[queue release];
[pool release];
}
I have an app that I am refactoring and I just implemented multithreading so that the UI may run smoother. In the iphone simulator I don't get any leaks but testing on my iPhone 3G running on iOS 4.2 I get a memory leak. I have done a lot of searching for the correct way to implement an autoreleasepool with an operationqueue, help will be greatly appreciated.
I have created an nsoperationqueue in my viewcontroller as such
- (void)loadData
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSOperationQueue *queue = [NSOperationQueue new]; // creates multithread for loading data without slowing UI
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(firstRun) object:nil];
[queue addOperation:operation];
[operation release];
[queue release];
[pool release];
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,您不应该只是创建然后释放队列。更自然的做法是创建该队列作为类的 ivars 之一,然后在视图控制器消失时释放它(您还可以取消任何挂起的操作并取消/等待任何正在运行的操作完成)。
其次,您不需要在创建操作并将其添加到队列中的方法中使用自动释放池,因为该方法是从主线程调用的。相反,您需要对象实际调用的方法中的自动释放池(这可能在另一个线程上运行)。
因此,您可能有以下内容(假设您将队列命名为 ivarqueue_):
您还可以按需初始化队列,因此不必在 viewDidLoad 中初始化,而是检查其存在,并在需要时在要添加操作的任何地方进行初始化。这可能包含在它自己的方法调用中,但是这里的延迟初始化可能并不是真正必要的,因为队列非常轻量级。
First, you shouldn't just create and then release the queue. It's more natural to create that queue as one of your class's ivars and then release it when your view controller goes away (you can also cancel up any pending operations and cancel/wait for any running operations to complete).
Second, you don't need the autorelease pool in the method that creates the operation and adds it in the queue since that method is being called from the main thread. Instead, you need the autorelease pool from the method your object actually calls (this is what may be running on another thread).
So, you might have the following (assuming you name your queue ivar queue_):
You could also initialize your queue on demand, so instead of initializing in viewDidLoad, check for its existence and initialize if necessary anywhere you'd add an operation. This might be wrapped in a method call of its own, but lazy initialization here probably isn't really necessary as queues are pretty light-weight.
您应该在 NSOperation 将调用的方法(在本例中为
firstRun
)的开头创建一个 NSAutoreleasePool,并在方法的末尾将其耗尽。You should create an
NSAutoreleasePool
at the start of the method that the NSOperation will invoke (in this case,firstRun
), and drain it at the end of the method.