【问题标题】:removeObjectAtIndex causes "message sent to deallocated instance"removeObjectAtIndex 导致“消息发送到释放的实例”
【发布时间】:2011-10-27 06:52:39
【问题描述】:

我正在将一些代码转换为 ARC。代码在 NSMutableArray 中搜索元素,然后查找、删除并返回该元素。问题是元素在“removeObjectAtIndex”后立即被释放:

- (UIView *)viewWithTag:(int)tag
{
    UIView *view = nil;
    for (int i = 0; i < [self count]; i++)
    {
        UIView *aView = [self objectAtIndex:i];
        if (aView.tag == tag) 
        {
            view = aView;
            NSLog(@"%@",view); // 1 (view is good)
            [self removeObjectAtIndex:i];
            break;
        }
    }
    NSLog(@"%@",view); // 2 (view has been deallocated)
    return view;
}

当我运行它时,我得到了

*** -[UIView respondsToSelector:]: message sent to deallocated instance 0x87882f0

在第二条日志语句中。

在 ARC 之前,我在调用 removeObjectAtIndex: 之前小心地保留了对象,然后自动释放它。我如何告诉 ARC 做同样的事情?

【问题讨论】:

  • [self removeObjectAtIndex:i]; 是做什么的?

标签: objective-c ios nsmutablearray automatic-ref-counting


【解决方案1】:

使用__autoreleasing 限定符声明UIView *view 引用,如下所示:

- (UIView *)viewWithTag:(int)tag
{
    __autoreleasing UIView *view;
    __unsafe_unretained UIView *aView;

    for (int i = 0; i < [self count]; i++)
    {
        aView = [self objectAtIndex:i];
        if (aView.tag == tag) 
        {
            view = aView;
            //Since you declared "view" as __autoreleasing,
            //the pre-ARC equivalent would be:
            //view = [[aView retain] autorelease];

            [self removeObjectAtIndex:i];
            break;
        }
    }

    return view;
}

__autoreleasing 会给你正是你想要的,因为在分配时,新指针被保留、自动释放,然后存储到左值中。

ARC reference

【讨论】:

  • 我认为__strong 是默认值?无论如何都不会这样做吗?
  • 谢谢雅各布。两件事:1) 我不得不使用 __unsafe_unretained 而不是 __weak,因为我希望保持 iOS 4 的兼容性。 2)原来ARC没有为该文件打开。愚蠢的错误。我必须通过并删除目标->构建阶段->编译源部分中的“fno-obj-arc”。
  • 开启ARC后原代码会崩溃吗?还是你还需要标记局部变量?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-22
  • 1970-01-01
  • 2016-08-28
  • 2011-06-16
  • 2013-08-30
相关资源
最近更新 更多