【问题标题】:Unwanted variable release (iOS)不需要的变量释放 (iOS)
【发布时间】:2013-05-23 15:11:55
【问题描述】:

我有 UIViewControllerstrong DataController 包含和管理项目列表 (itemsList)。在后者的初始化方法中,我从文件中读取项目,通过 Web 服务(和 ASIHTTPRequest)获取每个项目的附加信息,并将项目放入列表中,然后分配给 itemsList 属性。

使用同步请求一切正常,但我需要一个异步实现。我做到了,现在我的项目被解除分配(数据控制器没有),跟随请求等的代表也消失了。我怎样才能让物品保持活力?

在我的数据控制器中:

-(id)initDataController
{
self = [super init];
if (self)
{
    NSMutableArray *myList = [[NSMutableArray alloc] init];

    // Read items from file ...

    for (NSString *itemName in items) {
        MyItem *item = [[MyItem alloc] initWithParam:itemName];
        // Here the item has already been deallocated?!
        if (item) {
            [myList addObject:item];
        }
    }
    _itemsList = myList;
    return self;
}
return nil;
}

MyItem 类中,只有对服务器的标准请求和初始化。我认为问题应该出在一些缺失的strong/retain 上,但我不知道我应该把它放在哪里。

编辑:

列表的定义:

@property (nonatomic, copy) NSMutableArray *itemsList;

我想知道的是,这些项目甚至在我可以将它们放入列表之前就是nil...所以我尝试将属性设置为strong 而不是copy,但没有任何变化。

【问题讨论】:

  • 请在问题中添加 ivar _itemsList 的定义方式
  • 如果完成初始化需要响应数据,则无法从“init”方法中进行异步调用...
  • "这里的项目已经被释放了?!"不,他们不可能是,但他们可能是零。你在这里登录过项目吗?目前尚不清楚您的 for 循环与异步调用的关系。从您发布的内容来看,该循环似乎会在初始化数据控制器时立即运行,而不是在异步方法返回结果后运行。
  • 谢谢大家! @Wain 的答案是完美的,我将初始化和对服务器的调用分开,现在它可以工作了。

标签: iphone ios objective-c asihttprequest dealloc


【解决方案1】:
MyItem *item = ...

这个局部变量形成一个强引用。如果 initWithParam: 返回一个对象(不是 nil),那么在添加到列表之前就无法释放它(这会创建另一个强引用)。

请注意您的财产申报有缺陷:

@property (nonatomic, copy) NSMutableArray *itemsList;

copy 属性不适用于可变对象类型:分配属性时,合成的 setter 会在其上调用 copy,这会创建数组的 不可变 副本并分配那个。这与属性的类型相矛盾。

这实际上是另一个有用的 clang 编译器警告的好机会:当属性的类型符合 NSMutableCopying 时,它们不能被声明为 copy。铿锵队,你听到了吗?

【讨论】:

  • 非常感谢。阅读您的答案后,我意识到实际上我在 init 方法中没有返回任何内容,在我退出该方法之前,该项目已被释放。所以@Wain 在我的问题的评论中发布了完美的答案。但是,您能告诉我应该为数组使用哪些属性吗? nonatomic, strong?还是别的什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-24
  • 1970-01-01
  • 2012-07-17
  • 2014-12-17
  • 1970-01-01
相关资源
最近更新 更多