访问区块内的属性

时间:2014-12-12 19:33:37

标签: ios objective-c

我是iOS的新手,并且对他们的使用有一个快速的问题。说我有以下设置:

viewController.rowLabels = @[@"Hello", @"World"];
viewController.testBlock = ^(NSInteger itemIndex) {
// here i want to access another property of the viewController called foo
};

因此,如上所示,我想在块本身内访问视图控制器的另一个属性。我需要做一个* __弱 - >实现这一目标的强大任务,还是可以像NSLog(viewController.foo)一样简单地访问它?

2 个答案:

答案 0 :(得分:4)

简单但可能有问题的答案就是在执行其他属性时访问它:

viewController.rowLabels = @[@"Hello", @"World"];
viewController.testBlock = ^(NSInteger itemIndex) {
   ... viewController.foo ...
};

从您的片段中我们无法知道viewController是什么 - 例如它可以是来自此片段所在方法的局部变量,也可以是全局变量等。如果您只是阅读viewController中的值,就像您在这里一样,这并不重要[1]。

以上工作但可能存在问题:您可能有强引用周期viewController实例通过它的testBlock属性引用块,块引用viewController实例。如果这两个引用都很强(可能),那么您将具有循环依赖关系,并且viewController实例和块永远不会被系统释放。您可以使用引用来打破此循环:

viewController.rowLabels = @[@"Hello", @"World"];
__weak ViewController *weakViewController = viewController; // make a weak reference to the instance
viewController.testBlock = ^(NSInteger itemIndex)
{
   // temporarily make a strong reference - will last just as long as the block
   // is executing once the block finishes executing the strong reference is
   // removed and no strong reference cycle is left.
   ViewController *myController = weakViewController;
   // only execute if the `ViewController still exists
   if (myController != nil)
   {
      ... myController.foo ...
   }
};

HTH

[1]请注意,您正在阅读的值是对ViewController实例的引用,您可以修改该实例的属性,您不能做(并且不想做)的是修改哪个实例如果viewController是本地变量,则viewController引用。

答案 1 :(得分:0)

声明包含视图控制器对象的__block变量,如下所示:

__block __weak ViewController *blockVC = viewController;
viewController.testBlock = ^(NSInteger itemIndex) {
     NSLog(@"%@", blockVC.foo);
};

我已使用__block__weak,因为__block含蓄强,但添加__weak作为参考有助于打破强引用周期< / em>同时仍然使用__block的强引用来防止重新分配。


从iOS 5.0开始,似乎您可以创建__weak引用,而不是使用__block变量来访问块中的变量及其属性:

__weak ViewController * weakVC = viewController;
viewController.testBlock = ^(NSInteger itemIndex) {

    ViewController * strongVC = weakVC;
    if (strongVC) {
        NSLog(@"%@", strongVC.foo);
    }
};

但请注意,与将__weak__block存储类型结合使用不同,__weak指定可能无法使对象保持活动状态的引用,即可以解除分配,因此即使在块内也是如此,weakVC在你真正需要它之前可能是零。 (这就是单独使用if (strongVC)变量时需要__weak条件的原因。)