我将下面的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;
}
这要求实现为一个方便的init,但是如何检查指定的初始化程序self.init(命名:)是否成功?
extension UIImage {
convenience init(validateAndLoad name: String!) {
self.init(named: name)
// need to assert here if self.init fails
}
当self.init(named :)调用失败时,扩展程序的init将停止执行。
我尝试过创建一个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
}
但是有没有办法使用初始化程序来实现它?
答案 0 :(得分:7)
您现在可以在扩展程序中创建failable initializers;但是,初始化程序无法在协议中定义。
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
答案 1 :(得分:3)
与Objective-C不同,Swift初始化器不返回self,因此无法检查初始化失败。 Apple engineer suggested使用带有可选返回类型的工厂方法:
class ImageFactory {
class func validImage(named name: String) -> UIImage?
{
var image = UIImage(named:name)
assert(image != nil, "fail")
return image;
}
}
Apple工程师表示,他们正致力于使用工厂类方法来构建某种语言。
答案 2 :(得分:0)
我会写下面的方法:
extension UIImage {
class func validImage(named name: String) -> UIImage? {
var image = UIImage(named: name)
return image
}
在swift中你可以使用选项。如果此处没有给定名称的图像,则该方法将返回nil。