将局部变量作为块内的方法参数传递是否安全?

时间:2015-11-02 21:01:56

标签: objective-c objective-c-blocks local-variables retain-cycle

我知道Obj-C中的块允许你引用局部变量,这很好。但是我们可以安全地将局部变量从块内部传递给另一个方法吗?

我知道引用self会从内部块中冒险,但这会扩展到任何其他变量。

示例:

-(void)methodTakesObject(ObjectA *)object {

    ObjectB *b = object.b;
    __weak MyObject *weakSelf = self;

    [b doInBackground:^(NSArray *results) {
         [weakSelf doSomethingElseWith:results andWith:object andEvenWith:b];
    }
}

这里有三种“类型”的局部变量。块中的results,方法内创建的ObjectB以及传递给方法的ObjectA

我是否应该关注使用这些变量中的任何一个,并且确实在块内如何处理这些变量之间存在任何差异/关注

2 个答案:

答案 0 :(得分:1)

事实上,无论涉及哪些变量,都没有区别。

对保留周期的关注是,如果一个对象持有对块的强引用,那么在它被解除分配之前它不会被释放,而该块保存对该同一对象的强引用。这不会发生在这里。

一个名为-doInBackground:的方法似乎会运行块(立即启动),然后在块完成时释放它。因此,只要存在其他一些对象,就不会有块被保留的前景,因此没有希望它能够永久保留其他对象。

您甚至不需要使用弱自我约定来避免保留周期。你只会在不太可能的情况下使用它,你真的希望在块调用它的方法之前允许self有时被释放。更有可能的是,您应该使用对self的正常强引用,因为self的正常和/或期望是足够长的时间来执行该块。

答案 1 :(得分:0)

如果您担心保留周期, @ken 会给您一个完美的答案。至于对变量的担忧:

    从被调用的方法中保留
  1. object methodTakesObject:所以你不必担心它。 (如果它不是 nil ,那么)。
  2. b也由您保留,引用计数可能为2或 更多,所以你也不用担心它。
  3. 换句话说,你是安全的。