【问题标题】:Objective C block property is always nilObjective C 块属性总是 nil
【发布时间】:2013-09-12 21:15:43
【问题描述】:

我正在尝试了解有关 Objective C 块及其工作原理的更多信息。我已经建立了一个简单的项目,其中两个 UIViewControllers 嵌入在 Storyboard 的 UINavigationController 中。我正在尝试从第二个视图控制器更改第一个 ViewController 视图的背景颜色。这是一些代码:

ViewController.m

@implementation ViewController{
    ColorBlock _colorBlock;
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    if([segue.identifier isEqualToString:@"theSegue"]){
        SecondViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"SecondViewController"];
        vc.colorBlock = _colorBlock;
    }
}

- (IBAction)moveToSecondViewController:(id)sender {
    __weak id weakSelf = self;
    _colorBlock = ^{
        [[weakSelf view] setBackgroundColor:[UIColor redColor]];
    };
}

SecondViewController.h

typedef void (^ColorBlock)(void);

@interface SecondViewController : UIViewController

@property (readwrite, copy) ColorBlock colorBlock;

@end

SecondViewController.m

- (IBAction)buttonTapped:(id)sender {
    if(self.colorBlock){
        self.colorBlock();
    }
}

第一个 ViewController 的背景颜色没有改变,因为在 SecondViewController.m 的 buttonTapped: 方法中,self.colorBlock 为 nil,导致块调用不被调用。我以为我已经成功设置了prepareForSegue:sender: 中的块。为什么我的块属性为零?

【问题讨论】:

  • 你确定 moveToSecondViewController: 被调用(并在准备继续之前调用?)请仔细检查两者中的断点。
  • 是的 moveToSecondViewController: 被调用,我的 _colorBlock ivar 已成功设置。然后,prepareForSegue:sender: 被调用,ivar 被成功设置到 SecondViewController。

标签: ios objective-c objective-c-blocks


【解决方案1】:

在您的prepareForSegue 中,目标已被实例化。所以假设SecondViewController是目的地,你可以这样做:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    if([segue.identifier isEqualToString:@"theSegue"]){
        SecondViewController *vc = segue.destinationViewController;
        NSAssert([vc isKindOfClass:[SecondViewController class]], @"destination is not SecondViewController class");
        vc.colorBlock = _colorBlock;
    }
}

【讨论】:

  • @danh 不,他正在实例化 SecondViewController 的新副本。因此,他在一些他不想继续的幻影 VC 中设置了一个属性。
  • 哦。接得好。是的,应该这样做。我看到的是我在代码中所期待的,而不是那里的。 (虽然我认为断言有点过于防御性了)
  • 啊,是的,我忘记了 destinationViewController 属性。解决了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-14
  • 2018-07-17
  • 2013-01-07
  • 1970-01-01
  • 1970-01-01
  • 2011-06-10
  • 1970-01-01
相关资源
最近更新 更多