11

我正在将下面的 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(named:) 是否成功?

extension UIImage {
    convenience init(validateAndLoad name: String!) {
        self.init(named: name)

        // need to assert here if self.init fails
    }

当 self.init(named:) 调用失败时,扩展的 init 停止执行。

我尝试创建一个 UIImage 实例并将其分配给 self,但这不会编译。

当然,可以像在 ObjC 版本中一样使用辅助方法:

extension UIImage {

    class func validImage(named name: String) -> UIImage {
        var image = UIImage(named: name)
        assert(image == nil, "Image doesn't exist")
        return image
    }

但是有没有办法使用初始化器来实现呢?

4

3 回答 3

8

您现在可以在扩展中创建可失败的初始化程序;但是,初始化程序不能在协议中定义。

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
于 2015-01-07T20:00:30.660 回答
3

与 Objective-C 不同,Swift 初始化程序不返回 self,因此无法检查初始化失败。一位Apple 工程师建议使用带有可选返回类型的工厂方法:

class ImageFactory {

    class func validImage(named name: String) -> UIImage? 
    {
        var image = UIImage(named:name)
        assert(image != nil, "fail")
        return image;
    }
}

这位 Apple 工程师表示,他们正在努力在语言中构建一些可以使用工厂类方法解决的问题。

于 2014-06-13T17:19:47.243 回答
0

我会写如下方法:

extension UIImage {

class func validImage(named name: String) -> UIImage? {
    var image = UIImage(named: name)
    return image
}

在swift中,您可以使用选项。如果这里没有给定名称的图像,则该方法将返回 nil。

于 2014-06-13T16:28:46.107 回答