NSOperation(s) 仅在 iOS 3 设备上泄漏
Posted
技术标签:
【中文标题】NSOperation(s) 仅在 iOS 3 设备上泄漏【英文标题】:NSOperation(s) leaks only on iOS 3 device 【发布时间】:2010-09-30 18:16:22 【问题描述】:我有一些处理 CoreData 导入的 NSOperations 子类。我相信我已经勾选了大部分非主线程问题
我在main
方法
我为每个人创建一个NSManagedObjectContext
操作
这些操作被加载到一个 NSOperationQueue 中,最大并发操作数设置为 1。
该代码在 ios 4.0.1 上完美运行,但在 iOS 3.1.3 设备上会收到大量日志消息,如下所示
*** _NSAutoreleaseNoPool(): Object 0x5f926c0 of class NSCFDictionary autoreleased with no pool in place - just leaking
NSOperation 子类主方法
-(void) main
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@try
//Start Operation
//====================================
NSManagedObjectID *objID = nil;
NSError *err = nil;
id user = nil;
if( !(userID = [self __lookup:[self userID] inContext: [self threadContext]]) )
//Set the name of the element
user = [[self threadContext] objectWithID:objID];
//Update the name
[user setValue:@"John Doe" forKey:@"name"];
[user setValue:@"Hello world" forKey:@"status"];
if( ![[self threadContext] save:&err] )
DebugLog(@"Couldn't savechanges %@", err);
//====================================
//End Operation
@catch (NSException * e)
DebugLog(@"Exception %@",e);
//====================================
[pool drain];
__lookup:inContext:
方法
-(NSManagedObjectID*) __lookup:(id)aID inContext:(NSManagedObjectContext*) aContext
NSPredicate *predicate = nil;
NSEntityDescription *entity;
NSFetchRequest *fetchRequest = nil;
NSError *err = nil;
predicate = [NSPredicate predicateWithFormat:@"userID == %@",aID];
entity = [NSEntityDescription entityForName:@"User" inManagedObjectContext:aContext];
fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
[fetchRequest setPredicate:predicate];
[fetchRequest setEntity:entity];
//Only fetch id's for speed
[fetchRequest setResultType:NSManagedObjectIDResultType];
return [[aContext executeFetchRequest:fetchRequest error:&err] lastObject];
大多数其他方法实例方法,即threadContext
看起来类似于__lookup:inContext:
方法。我知道我不会为实例方法创建 Autorelease 池,但根据我对 autorelease 工作原理的理解,只要这些方法仅在 main 方法内部调用,在创建 NSAutoreleasePool
之后,应使用最外层池。我懒惰地创建诸如 NSManagedObjectContext 之类的对象,并且在大多数情况下不使用start
方法
【问题讨论】:
【参考方案1】:已解决,此操作使用 Dave Dribin 的 article 中的建议启动 NSURLConnection。但是,在可能的情况下,我尽量不要剪切和粘贴其他人的代码,所以我总是可以过滤我放入自己代码的内容。
原来我忘了添加这张支票
if( ![NSThread isMainThread] )
[self performSelectorOnMainThread:@selector(start)
withObject:nil
waitUntilDone:NO];
return;
确保start
方法在主线程上运行,其中NSAutoreleasePool
已经存在。简单的错误,简单的解决方案。
【讨论】:
以上是关于NSOperation(s) 仅在 iOS 3 设备上泄漏的主要内容,如果未能解决你的问题,请参考以下文章