実現したいこと
このGitHubに公開されているコードにて、ConcreteBlockの構造体のインスタンスの参照を外しもう一度参照を付け、msg_send!にて&*blockのようにしてブロックを渡しています。
これは、&TのTがRefEncodeを満たす時にmsg_send!へ値を渡せるようになることから、それを満たすためにやっているのだと思います。
というのも、ConcreteBlockにはDeref<Target = Block<A, R>>が実装されていて、参照外しを行うことでRefEncodeを満たすBlockにすることが可能です。なので、それをした後に&を付け&Tの形にすることで、msg_send!に渡せるようにするという具合です。
しかし、この&を付けても動く理由がわかりません。
発生している問題
なぜ&を付けても動く理由がわからないのかというと、Objective-Cのコードでブロックを作り渡す場合、completionHandler: ^()(...)のように*など書かずにそのままブロックを渡します。ここで、なぜObjective-Cではそのまま渡したのに、Rustの方でやる場合は&を付けても問題なく動くのかが疑問になります。
該当のソースコード
前述したこのコードの引用です。
rust
1 pub fn begin_sheet<F, W>(&self, window: &Window<W>, completion: F) 2 where 3 F: Fn() + Send + Sync + 'static, 4 W: WindowDelegate + 'static 5 { 6 let block = ConcreteBlock::new(move |_response: NSInteger| { 7 completion(); 8 }); 9 let block = block.copy(); 10 11 unsafe { 12 let _: () = msg_send![&*self.objc, beginSheet: &*window.objc, completionHandler: &*block]; 13 } 14 }
試したこと
その&を消してみたりしましたが、前述の&Tを満たさなくなりますので、エラーが出ました。
補足情報(FW/ツールのバージョンなど)
フレームワーク:objc2 クレート, block2 クレート
rustc: 1.74.0 (79e9716c9 2023-11-13)
回答1件
あなたの回答
tips
プレビュー
2023/12/30 09:35