Swift言語で関数ポインタぽい処理ができるのか試してみました。
関数ポインタとはC/C++などでよくつかう下記のようなヤツです。
typedef void (*TNotifyEvent)(System::TObject *Sender);
これはC++で書いたものですがこれを使う場合
void hoge(TObject *Sender){
}
void foo(TObject *Sender){
TNotifyEvent event1 = &hoge;
event1(Sender);
}
event1をコールするとhoge()関数が実行されます。
ここまではC++の例です。
Swiftの場合
Xcode11.5 Swift5.1で 同じような処理を行う場合下記のように書きました。
typealias TNotifyEvent = (_ sender: Any) -> Void
class THoge{
var event1: TNotifyEvent!
func f1(_ i: Int){
event1(i as Any)
}
}
class TFoo{
var hoge1: THoge
init() {
hoge1 = THoge()
hoge1.event1 = act1
}
func act1(_ sender: Any){
let i:Int = sender as? Int ?? 0
print(“Action “ + String(i))
}
}
上記のように記述することができます。
let foo1 = TFoo()
foo1.hoge1.f1(100)
TFooの中のTHoge.f1()というファンクションを実行してTFoo.act1()が実行されます。
下記のコードは、先程作成したTNotifyEventとAnyではなくジェネリックスで試してみました。
typealias TNotifyEvent<T> = (_ sender: T) -> Void
class THoge{
var event1: TNotifyEvent<Int>!
func f1(_ i: Int){
event1(i)
}
}
THogeクラス内のTNotifyEventがTNotifyEvent<Int>として利用できます。
このことによってAnyへのキャストの必要もなくなりコードがシンプルに実装できます。