我在viewControllers之间使用Blocks而不是委托进行回调,但是我无法弄清楚为什么这种情况不起作用:
所以我有一个调用detailViewController的mainViewController,当返回tableView时,需要重新加载mainViewController上的属性。
DetailViewController *actionDetail = [[DetailViewController alloc]initWithSaveBlock:^{
[self.tableView reloadData] //app crashes here
}];
当用户点击“保存按钮”时,调用detailViewController中的 由于某种原因, 当应用程序崩溃时,控制台中的消息为: 任何人都知道为什么这不起作用? 更新: SaveBlock定义如下- (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)
typedef void (^SaveBlock)();
@interface DetailViewController : UIViewController
{
}
@property(nonatomic,assign)SaveBlock saveBlock;
答案 0 :(得分:7)
您需要将阻止属性声明为copy
:
@property(nonatomic, copy) SaveBlock saveBlock;
您无法使用assign
或strong
。原因是你需要确保你有自己的块副本。传入的那个可能在堆栈框架上,当你运行块时可能会消失。因此,您需要触发Block_copy()
以确保将块复制到堆中(或者只有在已经存在的情况下才保留)。
[注意:这个解释非常简洁。如果你想完全理解它,我建议你去读一下块运行时。]
答案 1 :(得分:-1)
仅适用于ARC
您需要将阻止属性声明为strong
,并将其声明为copy
不需要。声明应该是:
@property (nonatomic, strong) SaveBlock saveBlock;
为什么不copy
?
当传递给你的initWithSaveBlock:
时,该块可能是堆栈分配的,或它可能不是。在任何一种情况下,您都需要保留它。如果块在堆栈上,那么保留它将使其被复制到堆上。如果块已经在堆上,则无需复制。因此,使用copy
将起作用,但可能包含冗余副本,使用strong
可以避免这种情况。
另请参阅this answer以获取解释。