我想创建一个Helper.swift
文件来添加一些在我的应用程序的不同部分有用的函数/方法。
我想知道什么是最佳实践(如果有的话):创建一个类,只创建类型方法或只创建函数?
答案 0 :(得分:4)
我通常倾向于在适当命名的类型上使用类型方法,以便为您的辅助方法提供上下文并避免污染全局命名空间。
在Swift中,结构体是这种结构的理想候选者:
struct Helper {
static func helpfulMethod() { ... }
}
我也在顶层类型中使用带有静态常量的嵌入式结构,以便在我的代码中对相关常量进行分组。
在编写自定义Swift类型时,通常应该首先考虑使用结构,并且只在继承时引用类,引用语义(与使用值语义的隐式复制相反)或所有权语义(unowned
/ {{ 1}})是必需的。在这种情况下,您的实用程序函数将是无状态的,并且没有可继承的内容,因此结构应该优先于类。
我认为,一般来说,Swift语言正在逐渐脱离全局函数,转而支持类型(和协议/泛型)提供的隐式命名空间。但它仍然在很大程度上取决于风格/个人偏好,对于像实用功能这样简单的事情,它的影响不大。
答案 1 :(得分:1)
没有必要创建类或结构。您可以直接将函数直接放在Helper.swift文件中。而且你甚至不需要通过编写import语句来导入这个文件。
要测试它,请创建一个名为helper.swift的文件,然后将以下代码行添加到文件中。 不需要任何类或结构。
import Foundation
func addTwo(x: Int) {
return x+2
}
要在任何其他文件中使用此函数,只需使用所需参数调用该函数。
let a = addTwo(9)
我更喜欢这种方法,因为当你调用函数时,你不必在类/结构的实例上调用它。其次,它会导致更清晰的代码,因为您不必使每个函数成为类函数或静态函数。
答案 2 :(得分:1)
我更喜欢类型方法,因为通过这种方式,您可以轻松区分您的方法。
假设您有50到60种方法,其中一些方法用于设计目的,一些方法用于计算目的,一些方法用于在服务器上获取和发布数据。
现在,在这种情况下,如果您将所有这些方法创建为全局,则很难识别并记住它们。
现在,如果您在某些类/结构中区分这些方法,如下所示:
DesignHelper
类/结构,并将所有这些方法放入class/static method
MathHelper
类/结构,并将所有这些方法放入class/static method
ConnectionHelper
类/结构,并将所有这些方法放入class/static method
通过这种方式,您可以轻松找到任何方法,它也有助于auto completion
。
谢谢。
答案 3 :(得分:1)
类函数通过单个类工作,但通常在整个应用程序中使用的那些函数将在相同的对象上重复。更简洁的方法是在将使用该函数的对象的扩展中定义您的函数。您可以将所有扩展名放在Helper.swift
中e.g。
extension UIColor
{
class func randomColor() -> UIColor
{
var randomRed:CGFloat = CGFloat(drand48())
var randomGreen:CGFloat = CGFloat(drand48())
var randomBlue:CGFloat = CGFloat(drand48())
return UIColor(red: randomRed, green: randomGreen, blue: randomBlue, alpha: 1.0)
}
}
使用此类page.backgroundColor = UIColor.randomColor()
所以你仍然可以根据用途将你的函数定义为类函数或对象函数,但是在对象的扩展中。
这可以保持代码清晰,因此您不会在整个代码库中通过帮助程序路由您的呼叫。它明确定义了需要该功能的对象。如果您发现在扩展函数中没有意义的代码,那么该函数可能需要重构为更集中的函数。
答案 4 :(得分:0)
解决方案#1:
class Helper {
class func classMethod() {
// TODO: play something
}
}
并称之为:
Helper.classMethod()
在Apple doc:
结构在代码中传递时总是被复制,并且不使用引用计数。
解决方案#2:
struct Helper {
static func classMethod() {
// TODO: do something
}
}
并使用它:
Helper.classMethod()
我认为解决方案#2 比解决方案#1 更好,因为它不会增加引用计数。
更新:我使用playground
进行了测试。请参阅以下结果:
答案 5 :(得分:0)
我不知道这是不是最好的做法,但这就是我的做法。
首先我声明一个协议:
protocol UtilityType { }
然后我扩展它(例如UIViewController的实用程序函数)
extension UtilityType where Self: UIViewController {
func setDefaultTitleAttributes() {
navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.whiteColor()]
}
}
我像这样使用它
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setDefaultTitleAttributes()
}
}
extension MyViewController: UtilityType {}