iphone - NSOperation仅在iOS 3设备上泄漏

标签 iphone multithreading nsoperation nsoperationqueue nsautoreleasepool

我有一些NSOperations子类可以处理CoreData导入。我相信我已经勾选了大多数非主线程问题

  • 我在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:方法相似。我知道我不会为实例方法创建自动释放池,但是根据我对自动释放的工作原理的理解,只要在创建了NSAutoreleasePool之后,仅在主方法内部调用这些方法,应该使用游泳池。我懒惰地创建诸如NSManagedObjectContext之类的对象,并且在大多数情况下不使用start方法

    最佳答案

    解决了此操作,该操作使用Dave Dribin在article中的建议启动NSURLConnection。但是,在可能的情况下,我尽量不要剪切并粘贴其他人的代码,因此我始终可以过滤自己要放入自己的代码中的内容。

    原来我忘了加这张支票

    if( ![NSThread isMainThread] ){
        [self performSelectorOnMainThread:@selector(start) 
                               withObject:nil 
                            waitUntilDone:NO];
        return;
    }
    

    这样可以确保start方法在已经存在NSAutoreleasePool的主线程上运行。简单的错误,简单的解决方案。

    关于iphone - NSOperation仅在iOS 3设备上泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3833564/

    相关文章:

    linux - 在 Linux 中增加线程的优先级

    multithreading - 从命令行在Minizinc中并行求解

    objective-c - 什么是nsoperation?如何使用它?

    ios - Advanced NSOperation - 在运行时添加依赖

    iphone - 是否有更简单的示例可用于使用 EAAccessory 执行串行通信?

    iphone - IOS 6 中的引用错误

    ios - iCloud - 在另一台设备上重命名打开的文档有时会失败

    java - Java 中的生产者/消费者。为什么我们需要两个条件?

    ios - 使 NSOperations 互斥

    html - 如何让 iPhone 网络应用模仿非网络应用?