Swift(Objective-Cの過去6年間)にはかなり新しく、ブロック内のEnum値を評価するときには少し問題があります。これを実証する最善の方法は例です。これを使用するときにSwiftで定義されたブロック内で列挙型を評価する
enum MyType {
case type1
case type2
}
class MySuperClass {
var type: MyType
var object: SomeObject
init(param: SomeObject) {
self.type = .type1
self.object = param
}
public func doSomething(handler block: @escaping (AnyObject) -> Void) {
self.type = .type2
// assign handler block to property, blah blah
object.execHandler(forMethod: "testing", completion: { (response) -> Void in
block(response)
})
}
public func reset() {
self.type = .type1
}
}
class MySubClass: MySuperClass {
override init(param: SomeObject) {
super.init(param: param)
let myBlock: MyBlockType = { (responseObject) -> Void in
// do some stuff
// ISSUE ARISES HERE
switch self.type {
case .type2:
print("Is type2")
default:
print("Do Nothing")
}
};
object.addHandler(forMethod: "testing", processBlock: myBlock)
}
}
はその後、私は単にこのような何かやってる:見ることができるように
let myObject = MySubClass(param: passingInAnObject) // the block is defined and setup (this sets the 'type' to .type2)
myObject.doSomething(handler: { (responseObject) -> Void in
print("completed")
})
// do some other stuff
// ...
object.reset()
を、doSomething
方法はとき、しかし、.type2
に列挙型を設定し、ブロックを実行しますブロックmyBlock
が評価され、古い値が使用されます(.type1
ではなく、.type2
)。したがって、コード実行は常にprint("Do Nothing")
行に分類されます。
私はSwiftの値によって列挙型がコピーされると信じていますので、このStackOverflowポスト(How to store a reference to an integer in Swift)に記載されているようにオブジェクトでこれらをラップしようとしましたが、無駄です。
これを克服する方法や、何か間違ったことをしている場合、私はいくつかアドバイスをいただきたいと思います。
何かが非同期で実行された後に呼び出されると仮定して、 'myBlock'が実行される前に、おそらく' object.reset() 'を呼び出すでしょう。 – dan
@danは、この厄介なことではありません。つまり、 'object.reset()'は補完ハンドラ内にあるはずです。本当に早くそれを見たことがあります。ありがとう!!! – Taz