首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >线程中的UIImage未被发布/覆盖

线程中的UIImage未被发布/覆盖
EN

Stack Overflow用户
提问于 2009-11-03 13:20:02
回答 4查看 2.2K关注 0票数 0

这似乎是从iPhone扫描图像的经典方法。我有一个线程从主线程被分派去扫描代码。它实际上每次创建一个新的UIImage,然后删除它。

代码语言:javascript
运行
复制
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    { 
        while (![thread isCancelled]) {
#ifdef DEBUG
            NSLog(@"Decoding Loop");
#endif
        //  [self performSelectorOnMainThread:@selector(updateImageBuffer) withObject:nil waitUntilDone:YES];           
            CGImageRef cgScreen = UIGetScreenImage();
            UIImage *uiimage = [UIImage imageWithCGImage:cgScreen];

            if (uiimage){
                CGSize size = [uiimage size];
                CGRect cropRect = CGRectMake(0.0, 80.0, size.width, 360); // Crop to centre of the screen - makes it more robust
#ifdef DEBUG
                NSLog(@"picked image size = (%f, %f)", size.width, size.height);
#endif
                [decoder decodeImage:uiimage cropRect:cropRect];
            }
            [uiimage release];
            CGImageRelease(cgScreen);
        }
    }
    [pool release];

问题在于,池的发布会导致ERROR_BAD_EXC (那是旧的经典版本)和程序炸弹。有人告诉我,没有必要调用uiimage发布,因为我没有显式地分配一个UIImage,但情况似乎并非如此。如果我把这条线去掉,内存的使用就会达到顶点,程序就会因为内存的缺乏而放弃。看来我不能按我喜欢的方式做这份工作。

有没有办法创建一个“就地”的UIImage?也就是说,是否有一个缓冲区被一次又一次地写入为UIImage?我怀疑那能行吗?

更新!

尝试在主线程上执行与UIKit相关的调用,如下所示:

代码语言:javascript
运行
复制
-(void)performDecode:(id)arg{

    // Perform the decoding in a seperate thread. This should, in theory, bounce back with a 
    // decoded or not decoded message. We can quit at the end of this thread.
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    { 
        while (![thread isCancelled]) {

#ifdef DEBUG
            NSLog(@"Decoding Loop");
#endif
            [self performSelectorOnMainThread:@selector(updateImageBuffer) withObject:nil waitUntilDone:YES];           

            if (uiimage){
                CGSize size = [uiimage size];
                CGRect cropRect = CGRectMake(0.0, 80.0, 320, 360); // Crop to centre of the screen - makes it more robust
#ifdef DEBUG
                NSLog(@"picked image size = (%f, %f)", size.width, size.height);
#endif
                [decoder decodeImage:uiimage cropRect:cropRect];
            }
        }
    }
    [pool drain];


#ifdef DEBUG
    NSLog(@"finished decoding.");
#endif


}

-(void) updateImageBuffer {
    CGImageRef cgScreen = UIGetScreenImage();
    uiimage = [UIImage imageWithCGImage:cgScreen];
    //[uiimage release];
    CGImageRelease(cgScreen);
}

然而,当EXC_BAD_ACCESS想要抓住UIImage的“大小”时,没有joy会竖起它丑陋的脑袋。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-11-03 18:38:51

正如其他人所述,您不应该释放从imageWithCGImage:返回的imageWithCGImage:。它是自动释放的。当池耗尽时,它会尝试向已经释放的图像对象发送一条发布消息,从而导致您的崩溃。

内存使用量不断上升的原因是,您只会在循环之外耗尽自动释放池。自动释放的对象在循环中不断积累。(顺便说一句,您需要在该方法的末尾释放您的自动释放池,因为它目前正在泄漏。)为了防止这种积累,您可以在循环中定期排出池。

然而,我建议切换到做[[UIImage alloc] initWithCGImage:cgScreen],然后释放图像时完成。我尽量避免在iPhone应用程序中使用自动释放的对象,以便更严格地控制内存使用和总体性能。

票数 1
EN

Stack Overflow用户

发布于 2009-11-03 13:46:22

UIGetScreenImage()是私有的,没有文档,所以您不能使用它。说它没有暗示你现在拥有CGImageRef cgScreen,那么你为什么要发布它呢?你也无法知道它是否是线程安全的,所以你应该假设它不是。然后你继续发布IImage *uiimage,你没有插入,保留或者复制,所以--你不拥有它。回顾文档

票数 1
EN

Stack Overflow用户

发布于 2009-11-03 13:39:58

在这种情况下,[uiimage release]绝对是错误的。此外,苹果强调所有UIKit方法都必须在主线程上执行。其中包括UIGetScreenImage()+[UIImage imageWithCGImage:]

编辑:,所以在错误的线程上调用-[UIImage size]时会得到一个异常。这可能不会让你感到惊讶,因为这是不允许的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1667303

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档