Iphone 块回调崩溃

Iphone 块回调崩溃,iphone,objective-c,ios,objective-c-blocks,Iphone,Objective C,Ios,Objective C Blocks,我在ViewController之间使用块而不是委托进行回调,但我无法找出此方案不起作用的原因: 因此,我有一个mainViewController,它在返回tableView时调用detailViewController,tableView是mainViewController上的一个属性,需要重新加载 DetailViewController *actionDetail = [[DetailViewController alloc]initWithSaveBlock:^{ [

我在ViewController之间使用块而不是委托进行回调,但我无法找出此方案不起作用的原因:

因此,我有一个mainViewController,它在返回tableView时调用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)
有人知道为什么这不起作用吗

更新:存储块的定义如下

typedef void (^SaveBlock)();

@interface DetailViewController : UIViewController
{

}
@property(nonatomic,assign)SaveBlock saveBlock;

您需要将块属性声明为
copy

@property(nonatomic, copy) SaveBlock saveBlock;
您不能使用
assign
strong
。原因是您需要确保您拥有自己的块副本。传入的一个可能位于堆栈帧上,当您运行该块时,该堆栈帧可能已消失。因此,您需要触发一个
Block\u copy()
,以确保该块被复制到堆中(如果它已经在堆中,则只保留它)


[注意:这一解释非常简洁。如果您想完全理解它,我建议您阅读有关块运行时的内容。]

您需要将块属性声明为
copy

@property(nonatomic, copy) SaveBlock saveBlock;
您不能使用
assign
strong
。原因是您需要确保您拥有自己的块副本。传入的一个可能位于堆栈帧上,当您运行该块时,该堆栈帧可能已消失。因此,您需要触发一个
Block\u copy()
,以确保该块被复制到堆中(如果它已经在堆中,则只保留它)


[注意:该解释非常简洁。如果您想完全理解,我建议您阅读有关块运行时的内容。]

仅适用于ARC下。


您需要将块属性声明为
strong
,不需要将其声明为
copy
。因此,宣言应该是:

@property (nonatomic, strong) SaveBlock saveBlock;
为什么不
复制

当传递到
initWithSaveBlock:
时,该块可能是堆栈分配的,也可能不是堆栈分配的。无论哪种情况,你都需要保留它。如果块位于堆栈上,则保留它将导致将其复制到堆上。如果块已经在堆上,则不需要复制它。因此,使用
copy
将起作用,但可能包括冗余副本,使用
strong
可避免这种情况


另请参见以获取解释。

仅适用于ARC下


您需要将块属性声明为
strong
,不需要将其声明为
copy
。因此,宣言应该是:

@property (nonatomic, strong) SaveBlock saveBlock;
为什么不
复制

当传递到
initWithSaveBlock:
时,该块可能是堆栈分配的,也可能不是堆栈分配的。无论哪种情况,你都需要保留它。如果块位于堆栈上,则保留它将导致将其复制到堆上。如果块已经在堆上,则不需要复制它。因此,使用
copy
将起作用,但可能包括冗余副本,使用
strong
可避免这种情况


另请参见以获取解释。

存储块属性的定义在哪里?我打赌它是
strong
/
retain
而不是
copy
,对吗?它需要
复制
。不,是分配,我已经更新了问题。分配也不对。它需要是
copy
saveBlock
属性的定义在哪里?我打赌它是
strong
/
retain
而不是
copy
,对吗?它需要
复制
。不,是分配,我已经更新了问题。分配也不对。它需要
copy
。哪里有文件证明
retain
copy
复制到堆中(如果堆中还没有的话)?也许这在ARC中是正确的(我不知道),但是retain不会在非ARC环境中将其移动到堆中。@CRD Block\u copy经过优化,如果它已经在堆中,则只保留它,因此使用copy没有问题。但是如果使用copy,则不需要了解堆栈和堆块。此外,它还定义了copy的语义,即它正确地将复制到堆中,或者如果已经在堆中,则只保留复制。复制是正确的选择,但我认为strong是错误的。如果以后要使用块,则必须复制其性质。也只是因为最近的叮当声,strong做了正确的事情(与副本完全相同),而且我在任何地方都找不到记录,所以它实际上可能只是一个结果。如果你能找到文件,上面说strong现在可以这样做,那么我很高兴地说我们现在可以使用strong了。否则,在这种情况下,复制是唯一使用正确语义的方法。哪里有文件证明
retain
copy
复制到堆中(如果堆中还没有)?也许在ARC中是这样的(我不知道),但是retain不会在非ARC环境中将其移动到堆中。@CRD Block\u copy经过优化,如果它已经在堆中,则只保留它,因此使用copy没有问题。但是如果使用copy,则不需要了解堆栈和堆块。此外,它还定义了copy的语义,即它正确地将复制到堆中,或者如果已经在堆中,则只保留复制。复制是正确的选择,但我认为strong是错误的。如果以后要使用块,则必须复制其性质。也只是因为最近的叮当声,strong做了正确的事情(与副本完全相同),而且我在任何地方都找不到记录,所以它实际上可能只是一个结果。如果您能找到文档,请