Давайте посмотрим на более простой (работающий) пример, в котором проблема с ядром не изменилась:
class ClassName {
static var bundle = Bundle(for: ClassName.self)
static func getBundle() -> Bundle {
return Bundle(for: self)
}
}
Во-первых, отметим, что Bundle(for: AnyClass)
принимает тип объекта.
1.Что касается переменных
Переменные на верхнем уровне, доступ к self
как ClassName
, который является типом экземпляра, независимо от того, объявлен ли он как let
/ var
/ lazy
/ вычислен, статичен или нет.
Итак:
static var bundle = Bundle(for: self)
совпадает с:
static var bundle = Bundle(for: ClassName())
Оба недопустимы и выдают следующую ошибку:
Невозможнопреобразовать значение типа «ClassName» в ожидаемый тип аргумента «AnyClass» (он же «AnyObject.Type»)
Конечно, это потому, что мы передаем тип экземпляра вместо ожидаемого типа объекта.
Решение:
static var bundle = Bundle(for: ClassName.self)
2.Что касается статических функций
Что касается статической функции, то она немного отличается.
Метатип, для которого вы вызываете статический метод, доступен вам в методе как self
(он просто передается как неявный параметр).
Ref: https://stackoverflow.com/a/42260880/2857130
В моем примере мы имеем:
static func getBundle() -> Bundle {
return Bundle(for: self)
}
Когда вы вызываете ClassName.getBundle()
, ClassName.Type
неявно передается функции.
Теперь внутри статической функции self
имеет тип ClassName.Type
, который является типом Object и может применяться непосредственно в * 1057.* или аналогичные функции, которые принимают тип объекта в качестве параметра.
Итак, статические функции обращаются к self
как ClassName.Type
, что совпадает с ClassName.self
, но не очевидно, поскольку оно передается неявно.
Вы можете подтвердить это поведение self
в функции static
, а также даже наблюдать, как self
ведет себя в обычной функции в следующем примере:
class ClassName {
static func check() {
print("static function check")
print(type(of: self)) //ClassName.Type
//same as
print(type(of: ClassName.self)) //ClassName.Type
//test
print(type(of: self) == type(of: ClassName.self)) //true
}
func check() {
print("normal function check")
print(type(of: self)) //ClassName
//test
print(type(of: self) == type(of: ClassName.self)) //false
}
}
ClassName.check()
ClassName().check()
Также показывает намчто нормальные функции обращаются к self
как ClassName
, что являетсяТип e, аналогичный переменным.
Резюме:
Bundle(for:)
принимает тип объекта - Переменные на верхнем уровне, доступ
self
как ClassName
, который является типом экземпляра - Доступ к обычным функциям
self
как ClassName
, который является типом экземпляра - Доступ к статическим функциям
self
как ClassName.Type
, который является объектомтип, поскольку он неявно передается в функцию