1

viewController間のコールバックにデリゲートの代わりにブロックを使用していますが、このシナリオが機能しない理由を理解できません。

したがって、mainViewControllerのプロパティであるtableViewを返すときに、detailViewControllerを呼び出している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]。2つのうちの1つを削除すると、アプリは正常に動作しているように見えますが、意図した動作が見当たらないことは明らかです。

アプリがクラッシュすると、コンソールのメッセージは次のようになります。

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

なぜこれが機能しないのか誰かが考えていますか?

更新: SaveBlockは次のように定義されています

typedef void (^SaveBlock)();

@interface DetailViewController : UIViewController
{

}
@property(nonatomic,assign)SaveBlock saveBlock;
4

2 に答える 2

7

copyブロック プロパティを次のように宣言する必要があります。

@property(nonatomic, copy) SaveBlock saveBlock;

assignまたはは使用できませんstrong。その理由は、ブロックの独自のコピーがあることを確認する必要があるためです。渡されたものはスタック フレーム上にある可能性があり、ブロックを実行するまでになくなっている可能性があります。Block_copy()したがって、ブロックがヒープにコピーされるように (または、既に存在する場合はそのまま保持されるように)をトリガーする必要があります。

[注: その説明は非常に簡潔です。完全に理解したい場合は、ブロック ランタイムについて読むことをお勧めします。]

于 2012-05-20T17:10:19.660 に答える
-1

ARC のみに適用

ブロック プロパティを として宣言する必要がありますstrong。必須でcopy はありません。したがって、宣言は次のようになります。

@property (nonatomic, strong) SaveBlock saveBlock;

なぜcopyですか?

ブロックに渡されると、initWithSaveBlock:スタックが割り当てられている場合とそうでない場合がありますいずれにせよ、それを保持する必要があります。ブロックがスタック上にある場合、それを保持するとヒープにコピーされます。ブロックがすでにヒープ上にある場合は、コピーする必要はありません。したがって、 usingcopyは機能しますが、冗長なコピーstrong含まれる可能性があります。

説明については、この回答も参照してください。

于 2012-05-20T20:34:05.377 に答える