guard 警卫
与if语句相同的是,guard也是基于一个表达式的布尔值去判断一段代码是否该被执行。与if语句不同的是,guard只有在条件不满足的时候才会执行这段代码。你可以把guard近似的看做是Assert,但是你可以优雅的退出而非崩溃。
guard let x = x where x > 0 else {
// 变量不符合条件判断时,执行下面代码
return
}
使用guard语句问题:
- 是对你所期望的条件做检查,而非不符合你期望的。又是和assert很相似。如果条件不符合,guard的else语句就运行,从而退出这个函数。
- 如果通过了条件判断,可选类型的变量在guard语句被调用的范围内会被自动的拆包 - 这个例子中该范围是fooGuard函数内部。这是一个很重要,却有点奇怪的特性,但让guard语句十分实用。
- 对你所不期望的情况早做检查,使得你写的函数更易读,更易维护。
文件结构与访问控制
在swift中,一个类不再分为interface(.h)与implementation(.m)两个文件实现,直接在一个.swift文件里进行处理。好处就是我们只需管理一份文件,以往两头奔波修改的情况就得到解放了,也减少了头文件与实现文件不同步导致的错误。
这时我们会想到,那么我们如何来定义私有方法与属性呢,在OC中我们通过在class extension中定义私有属性,在.m文件定义私有方法。
而在Swift中,我们通过Access Control来进行控制。
properties, types, functions等能够进行版本控制的统称为实体。
Public:可以访问自己模块或应用中源文件里的任何实体,别人也可以访问引入该模块中源文件里的所有实体。通常情况下,某个接口或Framework是可以被任何人使用时,你可以将其设置为public级别。
Internal:可以访问自己模块或应用中源文件里的任何实体,但是别人不能访问该模块中源文件里的实体。通常情况下,某个接口或Framework作为内部结构使用时,你可以将其设置为internal级别。
Private:只能在当前源文件中使用的实体,称为私有实体。使用private级别,可以用作隐藏某些功能的实现细节
一个小技巧,如果我们有一系列的私有方法,我们可以把它们组织起来,放进一个extension里,这样就不需要每个方法都标记private,同时也便于管理组织代码:
// MARK: Private
private extension ViewController {
func privateFunction() {
}
}
协议(Protocols)
语法:
在Objective-C中我们这么声明Protocol:
@protocol SampleProtocol
- (void)someMethod;
@end
而在Swift中:
protocol SampleProtocol
{
func someMethod()
}
在Swift遵循协议:
class AnotherClass: SomeSuperClass, SampleProtocol
{
func someMethod() {}
}
那么之前Objective-C的protocol中,我们可以标志optional。那在Swift中呢?
遗憾的是,目前纯Swift的protocol还不支持optional。但根据苹果官方论坛的一位员工的回答,未来Swift是会支持的。
protocol和delegate是紧密联系的。那么我们在Swift中如何定义Delegate呢?
protocol MyDelegate : class {
}
class MyClass {
weak var delegate : MyDelegate?
}
注意到上面的protocol定义后面跟着的class。这意味着该protocol只能被class类型所遵守。
并且只有遵守了class protocol的delegate才能定义为weak。这是因为在Swift中,除了class能够遵守协议,枚举和结构同样能够遵守协议。而枚举和结构是值类型,不存在内存管理的问题。因此只需要class类型的变量声明为weak即可。
利用Swift的optional chaining,我们能够很方便的检查delegate是否为Nil,是否有实现某个方法:
以前我们要在Objective-C这样检查:
if(self.dataSource && [self.dataSource respondsToSelector:@selector(titleForSegmentAtIndex:)]) {
thisSegmentTitle = [self.dataSource titleForSegmentAtIndex:index];
}
在Swift中,非常的优雅简洁。
if let thisSementTitle = dataSource?.titleFroSegmentAtIndex?(index){
}
新特性:
1.在Swift中,protocol变得更加强大,灵活:
2.class,enum,structure都可以遵守协议。
Extension也能遵守协议。利用它,我们不需要继承,也能够让系统的类也遵循我们的协议。
例如:
protocol myProtocol {
func hello() -> String
}
extension String:myProtocol{
func hello() -> String {
return"hello world!"
}
}
我们还能够用这个特性来组织我们的代码结构,如下面的代码所示,将UITableViewDataSource的实现移到了Extension。使代码更清晰。
// MARK: - UITableViewDataSource
extension MyViewcontroller: UITableViewDataSource {
// table view data source methods
}
类型转换 var a : Int = 0 var b : CGFloat = CGFloat(a) 先写类型,在写()
计算属性, 感觉更像一个方法
swift 3.0 会移除下面这种风格,用swift 代替
for(int i = 1; i <= 5; i++)
{
NSLog(@"%d", i);
}
改写为:
for index in1...5 {
print(index)
}
for index in stride(from: 1, through: 5, by: 2) {
print(index)
}// through是包括5, by 是步长
类方法 声明
+ (UIColor*)blackColor
对应的swift版本
class func blackColor() -> UIColor//类方法, 通过 class func 关键词声明
给函数设置默认值
func configureCellWithModel(Model: model,color:UIColor)
而在Swift中,default parameter values的引入让我们能够这样修改我们的代码:
func configureCellWithModel(Model: model,color:UIColor = UIColor.whiteColor())
可变参数
可变参数用于接受零个或多个值(个数不确定),通过在变量类型名后面加入(...)的方式定义
例子:
// 函数实现
func arithmeticMean(numbers: Double...) -> Double {
var total: Double = 0
for number in numbers {
total += number
}
return total / Double(numbers.count)
}
// 函数调用
arithmeticMean(1,2,3,4,5)