2013-09-12 4 views
0

Я пытаюсь узнать больше о блоках Objective C и о том, как они работают. Я создал простой проект с двумя UIViewControllers, встроенными в UINavigationController в Storyboard. Я пытаюсь изменить цвет фона первого представления ViewController со второго контроллера представления. Вот код:Объективное свойство блока C всегда равно нулю

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 в этом не меняется, потому что в buttonTapped: метода SecondViewController.m, self.colorBlock равен нулю, в результате чего вызов блока не вызывается. Я думал, что я успешно установил блок в prepareForSegue:sender:. Почему мое свойство блока nil?

+0

вы уверены moveToSecondViewController: вызывается (и вызывается перед подготовиться к Segue?) PLS двойную проверку с точки останова в обоих. – danh

+0

Да 'moveToSecondViewController:' вызывается и мой '_colorBlock' ivar успешно установлен. Затем вызывается 'prepareForSegue: sender:', и ivar успешно устанавливается на SecondViewController. – hgwhittle

ответ

3

В вашем 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; 
    } 
} 
+0

не то, что код в исходном посте? – danh

+1

@ danh Нет, он создает новую копию SecondViewController. Таким образом, он устанавливает свойство в каком-то фантомном VC, к которому он не переходит. – Rob

+0

oh. хороший улов. да, это должно это сделать. я видел то, чего ожидал в коде, а не то, что было там. (хотя я думаю, что утверждение немного слишком оборонительное) – danh

Смежные вопросы