在Swift中动态调用方法

时间:2015-05-11 23:42:32

标签: swift

我已经创建了一个预定义颜色库,可以在Swift和Objective-C中使用,我已经为Xcode重写了一个插件,可以在编辑器中预览颜色,以便它可以与我一起使用库(以及其他一些变化)。

该插件目前有一个已创建颜色的列表。我对这个解决方案并不感到兴奋,因为这意味着无论何时我改变颜色列表,我都必须在这里修改我的代码。另外,我不喜欢有一个数据结构,周围有大约1500种颜色和字符串。似乎并不高效或优雅。

我想要做的不是将所有颜色存储在内存中,而是在代码中遇到函数名时调用NSColor的正确函数。我发现我可以检查NSColor是否使用函数respondsToSelector响应选择器:但是调用performSelector:不满足我的需要,因为我需要来自调用的返回值。

有没有办法摆脱这个。

let colourDict [ String : NSColor ] = [
    "blackColor" : NSColor.blackColor(),
    "whiteColor" : NSColor.whiteColor() ]
...

let foundColour = colourDict[ colourMethodName ]

这样的事情。

if ( NColor.respondsToSelector ( Selector ( colourMethodName ) ) {
    foundColour = NSColor.performSelector ( Selector ( colourMethodName ) )
}

显然它不会是performSelector:function本身,但我正在寻找那种类型的功能,除了它会返回NSColor对象。

感谢。

2 个答案:

答案 0 :(得分:0)

由于您正在定义自己的命名色彩空间,因此您需要自己做一些事情,因为NSColor不会保留许多预定义的颜色。我可以想到两个选择:

您可以创建一个包含颜色的小型数据库,并将其作为资源加载到项目中。按名称查找RGBA值,然后按该定义创建颜色。

使用一个函数扩展NSColor,该函数可以打开名称以返回颜色。然后你不会把它们全部记在内存中。 (我的例子是使用UIColor,但NSColor也可以使用)

extension UIColor {
    class func colorByName(name:String) -> UIColor {
        switch name.lowercaseString {
            case "blackcolor":
                return UIColor.blackColor()
            case "whitecolor":
                return UIColor.whiteColor()
            case "redcolor":
                return UIColor.redColor()
            // etc
        default:
            return UIColor.clearColor()
        }
    }
}


let color = UIColor.colorByName("redcolor")

当然,如果你真的很聪明,你可以把它们组合起来,这样就可以在运行时更新颜色定义。

答案 1 :(得分:0)

我不明白Aaron Brager的原始建议有什么问题。从字典 of functions 开始:

let colourDict : [ String : () -> UIColor ] = [
    "blackColor" : UIColor.blackColor,
    "whiteColor" : UIColor.whiteColor,
    // ... and so on ...
]

这非常有效 - 比在内存中生成所有颜色并将它们保存在那里更有效 - 因为它只是一个指针列表,基本上。

要获得实际颜色,请按名称获取颜色功能,并将其命名为:

let actualColor = colourDict["blackColor"]!()