Swift代码规范

作者: 小小土豆dev | 来源:发表于2017-05-09 18:27 被阅读50次

    当你试图解决一个别人代码中的问题时,难得不是怎么解决这个问题,而是先得找到、读懂这段代码。

    推荐文档:https://github.com/raywenderlich/swift-style-guide#naming

    我在找同事写的代码

    一:工程目录结构规范

    1、除了注释外,所有的资源命名都用英文,不要用魔术数字、汉字。

    2、推荐一个规范的工程目录结构

    工程目录结构

    Macro['mækro]:存放公用头文件比如:URL,宏定义,通知,枚举等等。

    Storage['stɔrɪdʒ]:存放封装HTTP请求和数据库操作文件。

    Resources[risɔrsiz]:存放html、音频、视频、图片等资源文件。

    Extra['ɛkstrə]:存放第三方SDK,如:百度地图SDK,支付宝SDK等等

    Vendors['vɛndɚz]:存放工程中封装的一些公用方法 或 SDK。

    Control[kən'trol]:存放网络请求(HTTP)Manager、数据库(DB)操作等类文件。

    View[vju]:存放所有自定义界面View。

    Model['mɑdl]:负责解析HTTP下来的数据。

    Controller[kən'trolɚ]:存放所有控制器类。

    3、所有的ViewController都应继承自一个BaseViewController(大家懂的)。

    4、文件命名、类名应以相应模块英文单词为准,不要用魔术数字命名,比如:

    Controller目录

    5、StoryBoard使用:界面跳转用代码实现,不建议用拖关系线条,方便后期维护。

    6、界面适配,建议用 AutoLayout 放弃 Autoresizing,随着大屏iPhone推出,苹果主推 AutoLayout 技术。

    8、所有的类名和逻辑方法,要加注释。

    9、所有的公用方法,都抽成一个公用类里。

    10、不要用虚拟目录,如果需要在工程中添加新的文件夹,使用 Add File To 方法添加。

    11、推荐一个 ViewController 注释模板

    // MARK: - LifeCycle

    override func viewDidLoad() {

        super.viewDidLoad()

    }

    // MARK: - Intial Method

    // MARK: - HTTP Method

    // MARK: - Action Method

    // MARK: - Private Method

    // MARK: - UITableViewDataSource

    // MARK: - UITableViewDelegate

    // MARK: - CustomDelegate

    // MARK: - Target Method

    // MARK: - Setter Getter Method


    二:代码规范

    1、尽可能使你的工程中不要出现代码警告,因为警告过多时也会造成一些未知错误。对于第三方库中的警告,你也应该积极清除掉。

    2、Delegate方法名称

    建议:使用参数标签,并且在第一个参数使用下划线( _ )来代替一个明确的参数标签

    func namePickerView(_ namePickerView: NamePickerView, didSelectName name: String)

    func namePickerViewShouldReload(_ namePickerView: NamePickerView) -> Bool

    不建议:

    func didSelectName(namePicker: NamePickerViewController, name: String)

    func namePickerShouldReload() -> Bool

    3、属性赋值

    建议:

    let selector = #selector(viewDidLoad)

    view.backgroundColor = .red

    let toView = context.view(forKey: .to)

    let view = UIView(frame: .zero)

    不建议:

    let selector = #selector(ViewController.viewDidLoad)

    view.backgroundColor = UIColor.red

    let toView = context.view(forKey: UITransitionContextViewKey.to)

    let view = UIView(frame: CGRect.zero)

    4、类、函数注释

    给类加名称注释有很大的帮助,我们往往知道一个页面的 title,却不知道这个页面在工程中对应的类(尤其是当你要修改小伙伴写的代码)。如果你的小伙伴,给他的类加了名称注释,根据名称在工程中全局搜索,你将能很快搜到这个类。

    // 首页

    class HomeViewController: UIViewController {

    // class stuff here

    }

    5、if语句

    建议:

    if user.isHappy {

    // Do something

    } else {

    // Do something else

    }

    不建议:

    if user.isHappy

    {

    // Do something

    }

    else {

    / Do something else

    }

    6、变量声明

    建议:

    var data = ["A": 1.2, "B": 3.2]

    不建议:

    var data :[String:CGFloat] = ["A" : 1.2, "B":3.2]

    var data : [String:CGFloat] = ["A" : 1.2, "B":3.2]

    7、方法声明

    func reticulateSplines(spline: [Double]) -> Bool {

    // reticulate code goes here

    }

    如果函数参数较多,使用换行表示

    func reticulateSplines(spline: [Double],

                     adjustmentFactor: Double,

                     translateConstant: Int, comment: String) -> Bool {

                    // reticulate code goes here

    }

    8、声明变量

    建议:Swift有类型推断机制,可以根据初始化赋值的类型推断出变量、常量的值

    let width = 120.0                                    // Double

    let widthString = (width as NSNumber).stringValue    // String

    不建议:

    let width: NSNumber = 120.0                          // NSNumber

    let widthString: NSString = width.stringValue        // NSString

    9、调用方法

    建议:

    if let textContainer = self.textContainer {

    // do many things with textContainer

    }

    不建议:

    self.textContainer?.textLabel?.setNeedsDisplay()

    10、嵌套if语句

    建议:

    var subview: UIView?

    var volume: Double?

    if let subview = subview, let volume = volume {

    // do something with unwrapped subview and volume

    }

    不建议:

    var optionalSubview: UIView?

    var volume: Double?

    if let unwrappedSubview = optionalSubview {

        if let realVolume = volume {

            // do something with unwrappedSubview and realVolume

        }

    }

    11、定义空数组

    建议:

    var names: [String] = []

    var lookup: [String: Int] = [:]

    不建议:

    var names = [String]()

    var lookup = [String: Int]()

    13、数组

    建议:

    var deviceModels: [String]

    var employees: [Int: String]

    var faxNumber: Int?

    不建议:

    var deviceModels: Array<String>

    var employees: Dictionary<Int, String>

    var faxNumber: Optional<Int>

    14、闭包

    建议:

    resource.request().onComplete { [weak self]

    response in

    guard let this = self else {

        return

    }

    let model = this.updateModel(response)

    this.updateUI(model)

    }

    不建议:

    resource.request().onComplete { [unowned self] response in

    let model = self.updateModel(response)

    self.updateUI(model)

    }

    resource.request().onComplete { [weak self] response in

    let model = self?.updateModel(response)

    self?.updateUI(model)

    }

    15、循环语句

    建议:

    for _ in 0..<3 {

    print("Hello three times")

    }

    for (index, value) in dataArray.enumerated() {

    print("\(value) is at position #\(index)")

    }

    for index in stride(from: 0, to: dataArray.count, by: 2) {

    print(index)

    }

    for index in dataArray.reversed() {

    print(index)

    }

    不建议:

    var i = 0

    while i < 3 {

    print("Hello three times")

    i += 1

    }

    var i = 0

    while i < attendeeList.count {

    let person = attendeeList[i]

    print("\(person) is at position #\(i)")

    i += 1

    }

    16、分号(在Swift中不用给每个语句后面加分号,换行代表这条语句结束,如果两条语句写在同一行,则必须在第一条语句后加分号,但不建议这种写法)

    建议:

    let swift = "not a scripting language"

    不建议:

    let swift = "not a scripting language";

    17、if语句

    建议:

    if name == "Hello" {

    print("World")

    }

    不建议:

    if (name=="Hello")  {

    print("World")

    }

    18、在写代码时,应该遵循面向对象六大原则

    1、单一职责原则(SRP):一个类应该只有一个发生变化的原因。

    2、开放封闭原则(OCP):对扩展是开放的,而对修改是封闭的。

    3、Liskov替换原则(LSP):主要是通过抽象和多态来实现,而抽象和多态的实现又来自继承。

    4、依赖倒置原则(DIP):针对接口编程,而不是针对实现编程。

    5、接口隔离原则(ISP):使用多个隔离的接口,比使用单个接口要好。

    6、迪米特原则(LOD):一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。

    19、常用CGRect方法

    let greenView = UIView(frame: CGRect(x: 100, y: 100, width: 100, height: 100))

    // 获取view的最小X值,也就是这个view的X值

    let minX: CGFloat = greenView.frame.minX

    // 获取view的最大的X值,也就是这个view的X值+view的宽

    let maxX: CGFloat = greenView.frame.maxX

    // 获取view的最小Y值,也就是这个view的Y值

    let minY: CGFloat = greenView.frame.minY

    // 获取view的最大Y值,也就是这个view的Y值+view的高度

    let maxY: CGFloat = greenView.frame.maxY

    // 获取view的中点X

    let midX: CGFloat = greenView.frame.midX

    // 获取view的中点Y

    let midY: CGFloat = greenView.frame.midY

    20、协议:如果一个类中的协议太多时,可以用 extension 去实现协议

    建议:

    class MyViewController: UIViewController {

    // class stuff here

    }

    // MARK: - UITableViewDataSource

    extension MyViewController: UITableViewDataSource {

    // table view data source methods

    }

    // MARK: - UIScrollViewDelegate

    extension MyViewController: UIScrollViewDelegate {

    // scroll view delegate methods

    }

    不建议:

    class MyViewController: UIViewController, UITableViewDataSource, UIScrollViewDelegate {

    // all methods

    }

    21、工程中我们常用的是MVC目录(Controller、Model、View),为了好区分模块,我们又会在每个目录下创建功能目录文件夹,比如在Controller下创建Home(主页)、Order(订单)、Me(个人中心),依次类推,当模块较多时,这样也会导致工程看起来很乱。此时,我们可以这样划分:在每个功能目录下创建MVC目录(Controller、Model、View),这样把MVC细分到每个功能,这样就更简单了。

    相关文章

      网友评论

        本文标题:Swift代码规范

        本文链接:https://www.haomeiwen.com/subject/ccpbtxtx.html