Обработка ошибок инициализации класса в расширении Swift
Я переписываю категорию Objective C ниже в Swift:
@implementation UIImage (Extra)
+ (UIImage *)validImageNamed:(NSString *)name
{
UIImage *image = [self imageNamed:name];
NSAssert(image, @"Unable to find image named '%@'", name);
return image;
}
Это требует реализации в качестве удобства инициализации, но как я могу проверить, если назначенный инициализатор self.init(named:) успешно?
extension UIImage {
convenience init(validateAndLoad name: String!) {
self.init(named: name)
// need to assert here if self.init fails
}
Когда происходит сбой вызова self.init(named:), инициализация расширения прекращается.
Я попытался создать экземпляр UIImage и присвоить его себе, но это не компилируется.
Конечно, вспомогательный метод может использоваться как в версии ObjC:
extension UIImage {
class func validImage(named name: String) -> UIImage {
var image = UIImage(named: name)
assert(image == nil, "Image doesn't exist")
return image
}
Но есть ли способ реализовать это с помощью инициализатора?
3 ответа
Теперь вы можете создавать неудачные инициализаторы в расширениях; однако инициализаторы не могут быть определены в протоколе.
class Thing {
var text:String?
}
extension Thing {
convenience init?(text:String) {
self.init()
if text == "" {
return nil
} else {
self.text = text
}
}
}
let that = Thing(text: "Hello")
println(that?.text) //prints Optional("Hello")
let empty = Thing(text: "")
println(empty) //prints nil
В отличие от Objective-C, инициализаторы Swift не возвращают себя, поэтому проверка на ошибки инициализации невозможна. Инженер Apple предложил вместо этого использовать фабричный метод с необязательным типом возврата:
class ImageFactory {
class func validImage(named name: String) -> UIImage?
{
var image = UIImage(named:name)
assert(image != nil, "fail")
return image;
}
}
Инженер Apple указал, что они работают над тем, чтобы встроить что-то в язык, который обойдется с помощью методов класса фабрики.
Я бы написал метод, как показано ниже:
extension UIImage {
class func validImage(named name: String) -> UIImage? {
var image = UIImage(named: name)
return image
}
В Swift вы можете использовать дополнительные. Если здесь нет изображения с заданным именем, метод вернет ноль.