2012-05-20 4 views
1

Я использую блоки вместо делегатов для обратных вызовов между viewControllers, но я не в состоянии понять, почему этот сценарий не работает:блоки обратного вызова аварии

Так что у меня mainViewController, который звонит в detailViewController, когда возврат tableView, который является свойством mainViewController, необходимо перезагрузить.

DetailViewController *actionDetail = [[DetailViewController alloc]initWithSaveBlock:^{ 
     [self.tableView reloadData] //app crashes here 
}]; 

в detailViewController «Сохранить» вызывается, когда пользователь нажимает кнопку «Сохранить»

- (void)save 
{ 
    if (self.saveBlock) 
     self.saveBlock(); 

    [self dismissModalViewControllerAnimated:YES]; 
} 

по какой-то причине [self.tableView reloadData] не идет вместе с [self dismissModalViewControllerAnimated:YES]. Если я удалю одно из двух, приложение, похоже, работает нормально, очевидно, что я не вижу намеченного поведения.

Когда приложение разбивает сообщение в консоли:

Previous frame inner to this frame (gdb could not unwind past this frame) 

Любой идея, почему это не работает?

Update: SaveBlock определяется как этот

typedef void (^SaveBlock)(); 

@interface DetailViewController : UIViewController 
{ 

} 
@property(nonatomic,assign)SaveBlock saveBlock; 
+1

Где определение свойства 'saveBlock'? Я уверен, что это 'strong' /' keep', а не 'copy', правильно? Он должен быть «копировать». – mattjgalloway

+0

Нет, это назначено, я обновил вопрос – Oysio

+1

Ну, а не правильно. Он должен быть «копировать». – mattjgalloway

ответ

7

Вы должны объявить свойство блока, как copy:

@property(nonatomic, copy) SaveBlock saveBlock; 

Вы не можете использовать assign или strong. Причина в том, что вам нужно убедиться, что у вас есть собственная копия блока. Тот, который прошел, может находиться на стеке стека, которое может исчезнуть к тому моменту, когда вы запустите блок. Поэтому вам нужно вызвать Block_copy(), чтобы убедиться, что блок скопирован в кучу (или просто сохранен, если он уже существует).

[Примечание: это объяснение очень краткий. Я предлагаю вам идти читать о блок выполнения, если вы хотите, чтобы понять его полностью.]

+1

одноатомные звуки как действительно круто секретное ключевое слово. – Joel

+0

У меня есть еще один вопрос, мне нужно освободить блок (как?) При использовании копии? – Oysio

+0

Nope. В этом отношении все будет правильно для вас. – mattjgalloway

-1

Применяется под ARC ТОЛЬКО

Вы должны объявить свойство блока, как strong, объявляя его как copyне требуется. Таким образом, заявление должно быть:

@property (nonatomic, strong) SaveBlock saveBlock; 

Почему не copy?

При переходе к вашему initWithSaveBlock: блоку может быть стек выделяется, или оно не может быть. В любом случае вам нужно удержать. Если блок находится в стеке, то его сохранение будет заставить его скопировать на кучу. Если блок уже находится в куче, то его не нужно копировать. Таким образом, использование copy будет работать, но может включить резервную копию, используя strong, избегает этого.

См. Также this answer для получения пояснения.

+3

Где документировано, что 'keep' будет' копировать' в кучу, если он еще не находится в куче? –

+0

Возможно, это верно в ARC (я не знаю), но сохранение не переносит его в кучу в среде, отличной от ARC. – Joel

+0

@Joel - Ой, да, спасибо, что указали это. ARC знает, что копировать, MRC сохранить не делает. Добавлен всадник к ответу. – CRD

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