Swift编码规范

1 命名

使用驼峰式给类,方法或者变量等。类命名必须大写,然后方法名和变量应该以小写字母开始。

eg 首选的

private let maximumWidgetCount = 100

class WidgetContainer {

var widgetButton:UIButton?

let widgetHeightPercentage = 0.85

}

以下的方式是非首选的

let MAX_WIDGET_COUNT = 100

class app_widgetContainer {

var wBut:UIButton?

let wHeightPct = 0.85

}

对于函数和初始化方法,除非上下文比较明朗,对所有参数命名。包括外部参数名如果它使得函数调用更加可读

swift

func dateFromString(dateString:String)->NSDate

func convertPointAt(column column:Int.row:Int) ->CGPoint

func timedAction(afterDelay delay:NSTimeInterval,perform action:SKAction)->SKAction

应该这样调用

dateFromString(“2016-03-29”)

convertPointAt(column:7,row:13)

timedAction(afterDelay:1.0,perform:someOtherAction)

对于方法,遵循标准的苹果会话指的是第一个参数的方法名称:

swift

class Counter {

func combineWith(otherCounter:Counter,options:Dictionary?) {…}

func incrementBy(amount:Int) {….}

}

#enumerations枚举

使用大写的驼峰式命名定义枚举值

enum Shape {

case Rectangle

case Square

case Triangle

case Circle

}

#单调prose

指函数散文(教程、书籍、评论)包括从调用者的角度或“_”未命名参数的要求的参数名称

调用 “convertPointAt“通过你自己的初始化实现

如果你调用 dateFromString()_:必须确认你提供了一个带有“yyyy-MM-dd”的字符串

如果你通过ViewDidLoad()去调用timedAction(afterDelay:perform:)记得添加一个调整过的延迟值和一个执行的动作

你不应该直接调用数据源方法-tableView(_:cellForRowAtIndexPath:)

#类前缀

swift类型是由模块自动名称空间,其中包含它们,你不应该添加一个类前缀。如果两个名字来自不同模块碰撞可以通过加前缀消除歧义类型名称和模块名称。为什么加类前缀呢,就是为了消除多个模型的歧义这样编译器处理时好做区分。

#import SomeModules

let myClass = MyModule.UsefulClass()

#spacing间隔

缩进使用2个空间而不是保护空间和防止线包装标签。一定要设置这个偏好在Xcode和项目设置如下所示:

方法间隔和其他间隔总是在向同一行作为陈述句打开,但是在新的一行关闭

建议:你能预间隔通过选择一些代码例如 comman+A是选择所有然后control +i。Xcode模板中的一些有四个间隔tab的硬编码因此这是一个好的办法去修正它。

#首选的

if user.isHappy {

//Do something

}else {

//Do something else

}

#非首选的格式

if user.isHappy

{

//Do something

}

else {

//Do something else

}

方法之间应该有一个空行方法帮助视觉清晰度和组织。空格内方法应该单独的功能,但太多的部分在一个方法中通常意味着你应该重构为几个方法。

##comments注释

当它们是必须的,用注释去解释**why**代码的一个详细块做一些事情。注释应该保持最新或被删除

用。避免注释内联代码块,因为代码应尽可能自我文档。*例外:这并不适用于这些注释用于生成文档。*

##类和结构

使用哪个,记住,结构体是值类型,对于一些事使用结构体(没有一个特性)。一个数组包含a,b,c,和其他包含a,b,c的数组是一样的,它们是完全可交换的。你是否用第一个数组或是第二个完全没有关系,因为你代表的是准确的同一件事,这就是为什么数组是结构体

类属于引用类型,用类来声明一些事情有一个特性或一个特殊的生命周期。你用一个类建模一个人因为二个人的对象是二个不同的事情,仅仅因为二个人有相同的名字和生日,这并不意味它们是同一个人。但是人的生日能是一个结构体因为日期和另外一个日期是相同的,日期本身没有一个同一性。

有时候,事情是结构体但是必须遵从AnyObject 或以往已经用类来建模,试着尽可能紧密地遵从这些指引。

以下是一个例子-风格较好的类定义

class Circle:Shape {

var x:Int,y:Int

var radius:Double

var diameter:Double {

get {

return radius * 2

}

set {

radius = newValue /2

}

}

init(x:Int,y:Int,radius:Double) {

self.x = x

self.y = y

self.radius = radius

}

convenience init(x:Int,y:Int,diameter:Double) {

self.init(x:x,y:y,radius:diameter/2)

}

func describle() ->String {

return “I’m a circle at\(centerString()) with an area of\(computeArea())”

}

override func computerArea() ->Double {

return M_PI * radius * radius

}

override func centerString() ->String {

return “\(x),\(y)”

}

以上展示的例子-遵从下面的风格指导

1,加匹配类型给属性,变量,常量,声明参数和用括号的陈述句 例如:x:Int

2,如果它们分享一个共同的目的或上下文,在单行上定义多个变量和结构

3,缩排getter和setter定义和属性观察

4,不要增加修饰语例如 internal-当它们已经是默认的。简单来说,当重写一个方法时不要重复存取修饰符

#self的使用

简洁来说,自从swift不要求它去存取一个对象的属性或调用它的方法,消除了使用self。

当初始化器中区分属性名称和参数时,用self。当在一个闭包表达式中引用一个属性时,如果使用self容易造成循环引用进而会内存泄露

Eg

class BoradLocation {

let row:Int,column:Int

init(row:Int,column:Int) {

self.row = row

self.column = column

let closure  = {

print(self.row)

}

}

}

#协议一致性

当增加协议的一致性给类时,最好增加一个独立的类扩展给协议方法。这将保持相关的方法用协议分组,兵器简化指令去增加一个协议给一个有它相关方法的类。

不要忘记//MARK:-去注释保持事情更有组织

-首选的

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 here

}

-不推荐的

Class MyViewController:UIViewController,UITableViewDataSource,UIScrollViewDelegate {

//all methods

}

#计算属性

简洁说来,如果一个计算属性是只读的,省略get子句,当一个set子句是提供的,get子句仅仅是要求

eg,最佳选择

var diameter:Double {

return radius * 2

}

非最佳的写法

var  diameter:Double {

get {

return radius * 2

}

}

##函数声明

包含一个开括号在一行内定义一个短函数

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

}

对于带有长署名的函数而言,在适当的点中断 然后在下一行增加一个特别的缩排

func reticulateSplines(spline: [Double], adjustmentFactor: Double,

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

// reticulate code goes here

}

#闭包表达式

如果在参数列表的皆为有一个单独的闭包表达式参数,使用拖尾闭包,给闭包参数叙述性的名字

eg-最佳书写规范

UIView,animateWithDuration(1.0) {

self.myView.alpha = 0

}

UIView.animateWithDuration(1.0,animations: {

self.myView.alpha = 0

},

completion: { finished in self,myView.removeFromSuperView()

}

)

-非首选的书写规范

UIView.animateWithDuration(1.0,animations: {

self.myView.alpha = 0

})

UIView.animateWithDuration(1.0,

animations:{

self,myView.alpha = 0

}) { f in

self.myView.removeFromSuperView()

}

当上下文明朗的,单一表达式闭包用隐式返回

attendeeList.sort { a,b in

a > b

}

##类型

当可用时,总是使用swift本地类型。swift提供桥接到objective-C-因此你可用使用所有系列的方法

eg首选

let width = 120.0

let widthString = (width as NSNumber).stringValue

eg-糟糕的书写方式

let width:NSNumber = 120.0

let widthString :NSString = width.stringValue

在sprite kit代码中如果通过避免过多的转换来使代码更加简洁,用CGFloat

#constants常量

常量使用let关键字定义,变量则用var关键字去定义。如果变量的值将不做更改,用let代替var

如果编译器抱怨,定义任何事物用let,仅仅更改它为var。编译器会给你tip。

##可选值

当一个空值是可以被接收的,声明变量和函数返回值类型为可选值,对于实例变量(你知道的在使用前必须初始化)隐式强制解包用!例如在viewDidLoad中将被安装的子视图。

如果这个值仅仅存取一次或是在链中有多个可选值时,当你存取一个可选值时,使用可选链

例如

self.textContainer?.textLabel?.setNeedDisplay()

当解包一次或执行多重的操作时使用可选绑定更加方便

eg

if let textContainer = self.textContainer {

//do many things with textContainer

}

当命名可选变量或属性时,当他们的可选类型已经在类型中声明时避免这样的命名例如 optionalString,maybeView

-明智的选择

var subview:UIView?

var volume:Double?

var name:String?

//

if let subview = subview,volume = volume,name = name {

//do something with unwrapped subview ,volume and name

}

糟糕的命名

var optionalSubview:UIView?

var volume:Double?

if let unwrappedSubview = optionalSubview {

if let realVolume = volume {

//do something with unwrappedSubview and realVolume

}

}

#结构初始化器

最好使用本地的swift结构初始化器去代替原有的初始化器

明智的选择

let bounds = CGRect(x:40,y:40,width:100,height:80)

let centerPoint = CGPoint(x:97,y:87)

糟糕的使用

let bounds = CGRectMake(40,20,30,45)

let centerPoint = CGPointMake(97,87)

#类型推断

参考紧凑的代码,让编译器推断的类型常量或变量,除非你需要一个特定类型的默认 .例如,CGFloat,Int16

首要的选择规范

let message = “Click the button”

let currentBounds = computerViewBounds()

var names = [String]()

let maximumWidth:CGFloat = 106.5

糟糕的书写规范

let message :String = “Click the button”

let currentBounds :CGRect = computerViewBounds()

var names:[String] =[]

备注:下面这条指导原则意味着选择描述性的名字比以前更加重要。

#语法糖

喜欢快捷版本完整的泛型类型声明的语法。

eg:

var deviceModels:[String]

var employees:[Int:String]

var faxNumber:Int?

糟糕的书写规范

var deviceModels:Array

var employees:Dictionary

var faxNumber:Optional

#控制流

使用for-in代替for循环

首选的书写规范

for _ in 0..<3 {

print(“Hello,three times”)

}

for (index,person) in attendeeList.enumerate() {

print(“\(person) is at position  \(index)”)

}

糟糕的书写规范

for var i = 0;i < 3;i++ {

print(“hello,three times”)

}

for var i = 0;i < attendeeList.count;i++ {

let person = attendeeList[i]

print(“\(person) is at position \(i)”)

}

#分号

在你的代码中每一个陈述句后swift不要求分号,如果你希望在单行上结合多长陈述句,要加分号

不要在分号分开的单行写多重陈述句

唯一的例外是“for-conditional-increment”构造,这就需要分号。然而,选择“for-in”结构应该在可能的情况下使用。

首选的代码书写方式

let swift = “not a scripting language”

糟糕的书写方式

let swift = “not a scripting language”;

备注:

swift不同于JavaScript,在省略分号(通常被认为不安全)

#语言

用美式英语拼写去匹配苹果API

首选的书写方式

let  color = “red”

不建议采用的书写规范

let colour = “red”

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,069评论 4 358
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,212评论 1 287
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 105,912评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,424评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,741评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,194评论 1 206
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,553评论 2 307
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,289评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,923评论 1 237
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,251评论 2 240
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,775评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,144评论 2 249
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,698评论 3 228
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,936评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,658评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,214评论 2 267
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,159评论 2 258

推荐阅读更多精彩内容

  • 2014年的苹果全球开发者大会(WWDC),当Craig Federighi向全世界宣布“We have new ...
    yeshenlong520阅读 2,186评论 0 9
  • SwiftDay011.MySwiftimport UIKitprintln("Hello Swift!")var...
    smile丽语阅读 3,805评论 0 6
  • 花了周末的时间翻译raywenderlich.com的Swift编码规范(传送门), 原文是针对写作时Swift代...
    豆志昂扬阅读 7,561评论 2 43
  • 132.转换错误成可选值 通过转换错误成一个可选值,你可以使用 try? 来处理错误。当执行try?表达式时,如果...
    无沣阅读 1,180评论 0 3
  • 相亲是一种特殊的情况。刚开始我还有忌讳,有辱我的形象或者不想去,但是看到家人期待我目光,于是渐渐的接受了家人的一次...
    沐府墓主阅读 292评论 0 0