ios - Swift:符合声明类函数返回实例的协议(protocol)

标签 ios swift protocols

我想要一个通用协议(protocol)来返回给定类的新“随机”配置实例。

在 ObjC 中:

@protocol Random
+ (instancetype)random;
@end

@interface UIColor (Random)
<Random>
@end

@implementation
+ (instancetype)random {
    return [UIColor colorWith...];
}
@end

它适用于 ObjC,但我无法让它适用于 Swift。

在 Swift 中:

protocol Random {
    static func randomExample() -> Self
}

extension UIColor: Random {
    final class func randomExample() -> UIColor {
        return UIColor(red: ...)
    }
}

但是无论我如何配置它都会抛出错误。

我如何才能正确地为类方法返回符合类的实例制定协议(protocol)?

最佳答案

您的问题源于尝试从 randomExample 返回一个 UIColor,因为 randomExample 希望您返回 Self .

以下面的不正确为例:

// Here `Self` is `UIColor`.
extension UIColor: Random {
    class func randomExample() -> Self { 
        return UIColor(...) // Here's the problem...
    }
}

// Here `Self` is `MyColor`.
class MyColor: UIColor {}

因为 randomExample 没有被 MyColor 覆盖,MyColor 调用的 randomExample 会尝试返回一个 UIColor。但是,randomExample 期望返回 MyColor 实例。

要解决这个问题你可以这样做:

extension UIColor: Random {
    class func randomExample() -> Self {
        // `self` refers to the current class.
        // If this wasn't a class method you would use `self.dynamicType`
        return self(red: 0, green: 0, blue: 0, alpha: 0)
    }
}

let color1 = UIColor.randomExample() // color1 is a `UIColor`.
let color2 = MyColor.randomExample() // color2 is a `MyColor`.

如果您使用的是 Swift 2,则需要使用:

self.init(red: 0, green: 0, blue: 0, alpha: 0)

您可能还对以下内容感兴趣:Protocol func returning SelfImplementing NSCopying in Swift with subclasses .

关于ios - Swift:符合声明类函数返回实例的协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32464527/

相关文章:

ios - 从 Popover View 中呈现模态视图 Controller

json - JSON/NSJSONSerialization 的 Swift 问题

swift - 扩展 Foundation 类以符合 Swift 协议(protocol)

iphone - 如何理解NSObject,它既是协议(protocol)又是接口(interface)

ios - 声明方法不可用,因为 swift 5 中的特定 iOS 版本

ios - 设置背景图像后按钮变为蓝色

objective-c - 裁剪 UIImage

swift - 扫描 BLE 设备并将它们呈现在 UITableView 中

swift - Google Places Autocomplete API 未在我的 Tableview 中填充确切的地址

swift - 如何解决 Swift 不支持一流元类型的问题?