Swift thừa hưởng khái niệm metaclass của Objective-C: các lớp cũng được coi là các đối tượng. Lớp học của lớp học Foo
là Foo.self
, và nó thuộc loại Foo.Type
. Nếu Foo
kế thừa từ Bar
, thì Foo.self
cũng có thể được gán cho biến loại Bar.Type
. Điều này có ít nhất hai lợi ích:Tôi có thể bỏ một đối tượng metaclass vào một loại giao thức trong Swift không?
- nó cho phép ghi đè "phương pháp tĩnh";
- thật dễ dàng để tạo một thể hiện của một lớp không xác định theo cách an toàn và không sử dụng sự phản chiếu.
Tôi đặc biệt đang xem mục thứ hai ngay bây giờ. Chỉ cần chắc chắn rằng tất cả mọi người hiểu được những gì tôi là sau đó, đây là một ví dụ:
class BaseFoo {
var description: String { return "BaseFoo" }
}
class DerivedFoo: BaseFoo {
override var description: String { return "DerivedFoo" }
}
let fooTypes: [BaseFoo.Type] = [BaseFoo.self, DerivedFoo.self] // metaclass magic!
for type in fooTypes {
let object: BaseFoo = type() // metaclass magic!
println(object)
}
Bây giờ, tôi có một loạt các AnyClass
đối tượng (bất kỳ trường hợp metaclass thể được gán cho AnyClass
, giống như bất kỳ đối tượng có thể được gán đến AnyObject
) và tôi muốn tìm cái nào thực hiện giao thức đã cho. Giao thức sẽ khai báo một initializer, và tôi sẽ khởi tạo lớp giống như tôi làm trong ví dụ trên. Ví dụ:
protocol Foo {
init(foo: String)
}
class Bar: Foo {
required init(foo: String) { println("Bar initialized with \(foo)") }
}
class Baz {
required init() { println("I'm not a Foo!") }
}
let types: [AnyClass] = [Bar.self, Baz.self]
Cho đến nay rất tốt. Bây giờ, vấn đề đang xác định nếu lớp thực hiện giao thức. Vì các trường hợp metaclass có tính đa hình, tôi mong đợi có thể truyền chúng. Tuy nhiên, tôi dường như thiếu một cái gì đó, bởi vì Swift sẽ không cho phép tôi viết những dòng này:
for type in types {
if let fooType = type as? Foo.Type {
let obj = fooType(foo: "special snowflake string")
}
}
Các lỗi biên dịch tôi nhận được là:
lỗi: 'Foo' là không giống với 'AnyObject'
Có cách nào để xác định xem một cá thể metaclass đại diện cho một lớp thực hiện giao thức và có cách nào để truyền thể hiện đó vào một loại giao thức không?
Tôi đã cố gắng khai báo Foo
làm giao thức lớp học, nhưng dường như chưa đủ.
EDIT: Tôi chỉ thử với loại Any
, và trong khi nó không gây ra một lỗi cú pháp, nó bị treo trình biên dịch Swift.
Crashed trình biên dịch? [Lỗi tệp] (http://bugreport.apple.com). – rickster
Tôi đã làm điều đó rồi. – zneak
Yay! Đối với vấn đề thực tế, tôi không chắc metaclasses là introspectable trong Swift hiện tại. – rickster