NSZombieEnabled 破坏工作代码?

发布于 2024-09-05 04:33:43 字数 1866 浏览 3 评论 0原文

我在 UIImageManipulation.m 中有以下方法:

+(UIImage *)scaleImage:(UIImage *)source toSize:(CGSize)size
{
    UIImage *scaledImage = nil;
    if (source != nil)
    {
        UIGraphicsBeginImageContext(size);
        [source drawInRect:CGRectMake(0, 0, size.width, size.height)];
        scaledImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }
    return scaledImage;
}

我在不同的视图中调用它:

imageFromFile = [UIImageManipulator scaleImage:imageFromFile toSize:imageView.frame.size];

(imageView 是之前分配的 UIImageView)

这在我的代码中效果很好。我完美地调整了图像的大小,并且抛出了零错误。我在 build -> 下也没有弹出任何内容分析。但当我第二次打开 NSZombieEnabled 来调试不同的 EXC_BAD_ACCESS 问题时,代码就中断了。每一次。我可以关闭 NSZombieEnabled,代码运行得很好。我打开它,然后砰的一声。破碎的。我注释掉该调用,它又起作用了。每次,它都会在控制台中给我一个错误:-[UIImage release]:消息发送到已释放的实例0x3b1d600。如果“NSZombieEnabled”关闭,则不会出现此错误。

有什么想法吗?

--编辑--

好吧,这真是要了我的命。我已经在所有可以的地方设置了断点,但我仍然无法掌握这个东西。这是我调用 scaleImage 方法时的完整代码:

-(void)setupImageButton
{
    UIImage *imageFromFile;

    if (object.imageAttribute == nil) {
        imageFromFile = [UIImage imageNamed:@"no-image.png"];
    } else {
        imageFromFile = object.imageAttribute;
    }
    UIImage *scaledImage = [UIImageManipulator scaleImage:imageFromFile toSize:imageButton.frame.size];
    UIImage *roundedImage = [UIImageManipulator makeRoundCornerImage:scaledImage :10 :10 withBorder:YES];
    [imageButton setBackgroundImage:roundedImage forState:UIControlStateNormal];
}

另一个 UIImageManipulator 方法 (makeRoundCornerImage) 不应该导致错误,而只是如果我忽略了某些内容,我将整个文件放在 github 此处 上。

不过,这个方法有些问题。必须是。如果我把它注释掉,效果会很好。如果我把它留在里面,就会出错。但它不会在 NSZombieEnabled 关闭的情况下引发错误。

I have the following method in UIImageManipulation.m:

+(UIImage *)scaleImage:(UIImage *)source toSize:(CGSize)size
{
    UIImage *scaledImage = nil;
    if (source != nil)
    {
        UIGraphicsBeginImageContext(size);
        [source drawInRect:CGRectMake(0, 0, size.width, size.height)];
        scaledImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }
    return scaledImage;
}

I am calling it in a different view with:

imageFromFile = [UIImageManipulator scaleImage:imageFromFile toSize:imageView.frame.size];

(imageView is a UIImageView allocated earlier)

This is working great in my code. I resizes the image perfectly, and throws zero errors. I also don't have anything pop up under build -> analyze. But the second I turn on NSZombieEnabled to debug a different EXC_BAD_ACCESS issue, the code breaks. Every single time. I can turn NSZombieEnabled off, code runs great. I turn it on, and boom. Broken. I comment out the call, and it works again. Every single time, it gives me an error in the console: -[UIImage release]: message sent to deallocated instance 0x3b1d600. This error doesn't appear if `NSZombieEnabled is turned off.

Any ideas?

--EDIT--

Ok, This is killing me. I have stuck breakpoints everywhere I can, and I still cannot get a hold of this thing. Here is the full code when I call the scaleImage method:

-(void)setupImageButton
{
    UIImage *imageFromFile;

    if (object.imageAttribute == nil) {
        imageFromFile = [UIImage imageNamed:@"no-image.png"];
    } else {
        imageFromFile = object.imageAttribute;
    }
    UIImage *scaledImage = [UIImageManipulator scaleImage:imageFromFile toSize:imageButton.frame.size];
    UIImage *roundedImage = [UIImageManipulator makeRoundCornerImage:scaledImage :10 :10 withBorder:YES];
    [imageButton setBackgroundImage:roundedImage forState:UIControlStateNormal];
}

The other UIImageManipulator method (makeRoundCornerImage) shouldn't be causing the error, but just in case I'm overlooking something, I threw the entire file up on github here.

It's something about this method though. Has to be. If I comment it out, it works great. If I leave it in, Error. But it doesn't throw errors with NSZombieEnabled turned off ever.

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

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

发布评论

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

评论(2

暮凉 2024-09-12 04:33:43

NSZombieEnabled 的目的是检测在对象被释放后发送到对象的消息。您看到的控制台错误是 NSZombieEnabled,告诉您一条 release 消息正在发送到 UIImage 的已释放实例。通常,像这样的错误是由于对 release 的调用过多或对 retain 的调用不足而导致的。

在这种情况下,您的 scaleImage:toSize: 方法返回一个自动释放的 UIImage。您从 NSZombieEnabled 收到的错误消息表明您可能在返回该对象后释放该对象。这可以解释你的错误。当你的自动释放池耗尽时,它会尝试释放已经被释放的对象。

您将 imageFromFile 传递给 scaleImage:toSize:,然后将同一变量重新分配给返回值。这种习惯用法本身并没有什么问题,但确实需要额外小心才能避免像这样的内存错误。您将覆盖对原始对象的引用,因此您必须确保它在赋值之前自动释放,或者保存一个单独的引用,以便您可以在赋值之后手动释放。否则你的原始对象将会泄漏。

The purpose of NSZombieEnabled is to detect messages that get sent to objects after they've been deallocated. The console error you're seeing is NSZombieEnabled telling you that a release message is being sent to a deallocated instance of UIImage. Usually a bug like this is the result of too many calls to release, or not enough calls to retain.

In this case, your scaleImage:toSize: method returns an autoreleased UIImage. The error message you're getting from NSZombieEnabled suggests that you may be releasing this object after it gets returned. This would explain your bug. When your autorelease pool drains it would try to release an object that's already been deallocated.

You're passing imageFromFile to scaleImage:toSize:, and then reassigning that same variable to the return value. There's nothing wrong with this idiom per se, but does require some extra care to avoid memory bugs like this one. You're overwriting your reference to the original object, so you either have to make sure it's autoreleased before the assignment, or save a separate reference that you can manually release after the assignment. Otherwise your original object will leak.

内心激荡 2024-09-12 04:33:43

该错误是由于 UIImageManipulatormakeRoundedCornerImage 方法中正在进行的释放所致。仍然不确定为什么在没有打开 NSZombieEnabled 的情况下它没有被拾取,但事实就是如此。

您可以在我在原始问题中发布的要点中找到有问题的行:第 74 行。

The error was due to a release going on in the makeRoundedCornerImage method from UIImageManipulator. Still not sure why it wasn't getting picked up without NSZombieEnabled turned on, but that's what it was.

You can find the offending line in the Gist I posted in the original question: Line 74.

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