Swift Extensions最佳实践

时间:2016-10-09 19:07:20

标签: ios swift swift3

我最近沉迷于Extensions。我发现有一件事是一个巨大的PITA,我想知道我在哪里为ArrayNSManagedObject之类的东西隐藏了一个有用的方法。

我所做的是将我的扩展名放在名为NSObject的{​​{1}}类文件中,并按字母顺序列出类扩展名。

它有效,但我想看看它是否与最佳实践保持一致。如果没有,跟踪CustomExtensions的最佳方式是什么?

这就是我所做的:

Extensions

3 个答案:

答案 0 :(得分:5)

我不认为"最佳做法"围绕这个问题已经弄清楚了。那就是说,这是MHO:

最终,我对待这些扩展的方式与在C中执行全局功能的方式相同。毕竟,这基本上就是它们的本质。具有特殊语法的全局函数......

如果扩展仅用于一个文件,那么我将扩展名放在同一个文件中。在我完成的时候,我最终得到了其中的一些。例如,您的formatAsTimeString是一种视图模型。如果它由单个视图控制器使用,我会将其保留在视图控制器的文件中。

如果扩展名由多个类使用,那么我将其分解为单独的文件。我将在扩展名后命名该文件。因此,例如,如果在多个文件中使用formatAsTimeString,那么我将有一个名为" Int + formatAsTimeString.swift"的文件。扩展可以存在的地方。

如果有许多相关的函数,那么我将它们放在同一个文件中,并根据函数的抽象概念命名文件。如果我选择在不同的程序中使用它们,我通过想象它们是否都必须一起移动来决定函数是否相关...例如,我可能有其他时间字符串相关的函数...

答案 1 :(得分:2)

我很乐意为此提供良好的“官方”指南!但是正如前面提到的,随着我们的前进,人们正在解决这个问题。

ViewController-Extensions

我发现一个有趣的用途是更复杂的类的文件内扩展,例如ViewController。

代替:

public class MainViewController: UIViewController, SpecialDelegate {
  // functions
}

您可以将每个导入扩展到其自己的扩展名中:

public class MainViewController: UIViewController {
  // functions
}

extension MainViewController: SpecialDelegate {
  // functions
}

这些有效地简化了格式设置,并且使组织扩展类(尤其是大型类/项目)更容易。请注意,这些文件应保留在同一文件中,或至少保留在主文件旁边的文件中。

简单添加的功能

对于像这样的简单扩展:

extension Int {
  /**
   Returns true when the integer is even.
   */
  var isEven: Bool {
    return self % 2 == 0
  }
}

我通常有一个标记为extensions的文件夹,其中存放了所有扩展文件。我目睹了更复杂的项目,这些文件与使用它们的位置更加接近,但是我不同意这种用法。

毕竟,应该在整个项目中使用扩展名,将其隐藏起来会使查找某个扩展名是否已经存在更加困难。

高度专业化的功能

如此处其他答复所述,为在其他地方不使用的用例创建文件专用扩展名,并将其放入使用位置的文件中

fileprivate extension String {
  // Highly specialized function that will NEVER be used anywhere else
}

扩展名

我注意到写扩展文件的各种类型。当我开始进行iOS-dev开发时,主要的指导方针是编写String-Extension.swift。如今,String+Extension.swift似乎赢了。

此外,许多人将添加的功能的名称写到文件中,例如Int+IsEven.swift,但这仅在每个文件只有一个功能时才有用。

答案 2 :(得分:1)

使用Swift3,我通常倾向于使用' fileprivate'如果扩展名仅用于一个文件。

fileprivate extension Date
{
    func toString( dateFormat format  : String ) -> String
    {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = format
        return dateFormatter.string(from: self)
    }
}