Đây là một câu hỏi tuyệt vời và trong khi Chris Lattner cố tình không muốn hỗ trợ tính năng này, tôi cũng như nhiều nhà phát triển, cũng không thể bỏ qua cảm giác của mình đến từ các ngôn ngữ khác, nơi đây là một nhiệm vụ tầm thường. Có rất nhiều unsafeBitCast
ví dụ, hầu hết trong số chúng không hiển thị hình ảnh đầy đủ, đây là một ví dụ chi tiết hơn :
typealias SwfBlock = () -> ()
typealias ObjBlock = @convention(block) () -> ()
func testSwfBlock(a: SwfBlock, _ b: SwfBlock) -> String {
let objA = unsafeBitCast(a as ObjBlock, AnyObject.self)
let objB = unsafeBitCast(b as ObjBlock, AnyObject.self)
return "a is ObjBlock: \(a is ObjBlock), b is ObjBlock: \(b is ObjBlock), objA === objB: \(objA === objB)"
}
func testObjBlock(a: ObjBlock, _ b: ObjBlock) -> String {
let objA = unsafeBitCast(a, AnyObject.self)
let objB = unsafeBitCast(b, AnyObject.self)
return "a is ObjBlock: \(a is ObjBlock), b is ObjBlock: \(b is ObjBlock), objA === objB: \(objA === objB)"
}
func testAnyBlock(a: Any?, _ b: Any?) -> String {
if !(a is ObjBlock) || !(b is ObjBlock) {
return "a nor b are ObjBlock, they are not equal"
}
let objA = unsafeBitCast(a as! ObjBlock, AnyObject.self)
let objB = unsafeBitCast(b as! ObjBlock, AnyObject.self)
return "a is ObjBlock: \(a is ObjBlock), b is ObjBlock: \(b is ObjBlock), objA === objB: \(objA === objB)"
}
class Foo
{
lazy var swfBlock: ObjBlock = self.swf
func swf() { print("swf") }
@objc func obj() { print("obj") }
}
let swfBlock: SwfBlock = { print("swf") }
let objBlock: ObjBlock = { print("obj") }
let foo: Foo = Foo()
print(testSwfBlock(swfBlock, swfBlock))
print(testSwfBlock(objBlock, objBlock))
print(testObjBlock(swfBlock, swfBlock))
print(testObjBlock(objBlock, objBlock))
print(testAnyBlock(swfBlock, swfBlock))
print(testAnyBlock(objBlock, objBlock))
print(testObjBlock(foo.swf, foo.swf))
print(testSwfBlock(foo.obj, foo.obj))
print(testAnyBlock(foo.swf, foo.swf))
print(testAnyBlock(foo.swfBlock, foo.swfBlock))
Phần thú vị là cách nhanh chóng chuyển SwfBlock sang ObjBlock, nhưng trong thực tế, hai khối SwfBlock được truyền sẽ luôn có giá trị khác nhau, trong khi ObjBlocks thì không. Khi chúng ta chuyển ObjBlock sang SwfBlock, điều tương tự cũng xảy ra với chúng, chúng trở thành hai giá trị khác nhau. Vì vậy, để bảo vệ tài liệu tham khảo, nên tránh kiểu ép kiểu này.
Tôi vẫn đang hiểu toàn bộ chủ đề này, nhưng một điều tôi mong ước là khả năng sử dụng @convention(block)
trên các phương thức class / struct, vì vậy tôi đã gửi một yêu cầu tính năng cần bỏ phiếu hoặc giải thích lý do tại sao đó là một ý tưởng tồi. Tôi cũng có cảm giác rằng cách tiếp cận này có thể xấu tất cả cùng nhau, nếu vậy, bất cứ ai có thể giải thích tại sao?
MyClass.self