swift关键字

一 @mutating 修饰在方法前 修改本属性的值
swift的两种类型:值类型引用类型
值类型

对于值类型,即结构体和枚举,其并不能直接在实例方法中修改实例属性的值,Swift中提供了另一种方式,如果真有如此的需求,开发者可以使用mutating关键字将实例方法声明成可变的,实际上,如果在可变的实例方法中修改了值类型属性的值,是会创建一个新的实例来代替原来的实例的,示例如下:

struct Point {
    var x:Double
    var y:Double
    //  此处修改了属性的值
    mutating func move(x:Double,y:Double) {
        self.x+=x
        self.y+=y
    }
}
var point = Point(x: 1, y: 1)
print(point)
point.move(3, y: 3)
print(point)

在值类型实例的可变方法中修改属性的值,实际上就是创建了一个新的实例,上面的写法和下面的写法原理是一样的:

struct Point {
    var x:Double
    var y:Double
    //  此处修改了属性的值
    mutating func move(x:Double,y:Double) {
        self = Point(x: self.x+x,y: self.y+y)
    }
}

传递的是参数的一个副本,这样在调用参数的过程中不会影响原始数据。

类与结构体的区别
当开发者在代码中传递这些实例时,结构体总是被复制,而类则是被引用。这是结构体和类的最本质区别。类通过引用计数允许一个类实例的多处引用

引用类型

把参数本身引用(内存地址)传递过去,在调用的过程会影响原始数据,
swift中 class是引用类型,其它的Int、 Float、 Bool、 Character、 Array、 Set、 enum、 struct全都是值类型

二 @inout 让值类型以引用方式传递 即:声明函数时,在参数前面用inout修饰,函数内部实现改变外部参数

swift 3.0 inout 放在参数类型前修饰 eg. fir: inout Int

有时候我们需要通过一个函数改变函数外面变量的值(将一个值类型参数以引用方式传递),这时,Swift提供的inout关键字就可以实现。

var value = 50
print(value)  // 此时value值为50

func increment(value: inout Int, length: Int = 10) {
    value += length
}

increment(&value)
print(value)  // 此时value值为60,成功改变了函数外部变量value的值
注意
inout修饰的参数是不能有默认值的(例子中length = 10被赋予默认值),有范围的参数集合也不能被修饰;
一个参数一旦被inout修饰,就不能再被var和let修饰了。
三 final 防止类被继承

Swift中的final修饰符可以防止类(class)被继承,还可以防止子类重写父类的属性、方法以及下标。需要注意的是,final修饰符只能用于类,不能修饰结构体(struct)和枚举(enum),因为结构体和枚举只能遵循协议(protocol). 虽然协议也可以遵循其他协议,但是它并不能重写遵循的协议的任何成员,这就是结构体和枚举不需要final修饰的原因。

class Shape {
    final var center:(Double,Double)
    init(){
        center = (0,0)
    }
}
四 override 子类重写父类方法

默认子类也会继承父类的构造方法,如果子类需要实现自己的构造方法,可以对父类的方法进行覆写,使用override关键字

class Rect: Shape {
    var size:(Double,Double)=(0,0)
    override init(){
        super.init()
        super.center = (1,1)
    }
}

通过super关键字可以调用父类的属性和方法,同样,也可以使用override关键字来对属性进行get和set的覆写。同样也可以重写属性的观察期willset和didset

五 unowned 无主引用

某个类必须保有另一个类的示例,这个实例不能为nil,但是这个属性又不能影响其原始实例的释放,这种情况也会造成循环引用,示例如下:

class MyClassFive{
    unowned var cls:MyClassSix
    init(param:MyClassSix){
        cls = param
    }
    deinit{
        print("ClassFive deinit")
    }
}
class MyClassSix{
    var cls:MyClassFive?
    deinit{
        print("ClassSix deinit")
    }
}
var obj6:MyClassSix? = MyClassSix()
var obj5:MyClassFive? = MyClassFive(param: obj6!)
obj6?.cls = obj5
obj5=nil
obj6=nil

关于弱引用和无主引用,其区别主要是在于:

  • 弱引用用于解决Optional值的引起的循环引用。
  • 无主引用用于解决非Optional值引起的循环引用。
  • 个人以为,弱引用可用下图表示:
  • 无主引用可用如下图表示:

若将上面的代码修改如下,程序会直接崩溃:

class MyClassFive{
    unowned var cls:MyClassSix
    init(param:MyClassSix){
        cls = param
    }
    deinit{
        print("ClassFive deinit")
    }
}
class MyClassSix{
    var cls:MyClassFive?
    deinit{
        print("ClassSix deinit")
    }
}
var obj6:MyClassSix? = MyClassSix()
var obj5:MyClassFive? = MyClassFive(param: obj6!)
obj6?.cls = obj5
obj6=nil
obj5?.cls

两类实例引用的属性都为非Optional值的时候,可以使用无主引用与隐式拆包结合的方式来解决,这也是无主引用最大的应用之处,示例如下:

class MyClassSeven{
    unowned var cls:MyClassEight
    init(param:MyClassEight){
        cls = param
    }
    deinit{
        print("ClassSeven deinit")
    }
}
class MyClassEight{
    var cls:MyClassSeven!
    init(){
        cls = MyClassSeven(param:self)
    }
    deinit{
        print("ClassEight deinit")
    }
}
var obj7:MyClassEight? = MyClassEight()
obj7=nil

除了在两个类实例间会产生循环引用,在闭包中,也可能出现循环引用,当某个类中包含一个闭包属性,同时这个闭包属性中又使用了类实例,则会产生循环引用,示例如下:

class MyClassNine {
    var name:String = "HS"
    lazy var closure:()->Void = {
        //闭包中使用引用值会使引用+1
        print(self.name)
    }
    deinit{
        print("ClassNine deinit")
    }
}
var obj9:MyClassNine? = MyClassNine()
obj9?.closure()
obj9=nil
//不会打印析构信息

Swift中提供了闭包的捕获列表来对引用类型进行弱引用或者无主引用的转换:

class MyClassNine {
    var name:String = "HS"
    lazy var closure:()->Void = {
        [unowned self]()->Void in
        print(self.name)
    }
    deinit{
        print("ClassNine deinit")
    }
}
var obj9:MyClassNine? = MyClassNine()
obj9?.closure()
obj9=nil

捕获列表以中括号标识,多个捕获参数则使用逗号分隔。

swift中常用关键字
  • 用作声明的关键字:

classdeinitenumextensionfuncimportinitletprotocolstaticstructsubscripttypealiasvar

  • 用作语句的关键字

breakcasecontinuedefaultdoelsefallthroughifinforreturnswitchwherewhile

  • 用作表达和类型的关键字:

asdynamicTypenewissuperselfSelfType__COLUMN____FILE____FUNCTION____LINE__

  • 特定上下文中被保留的关键字:

associativitydidsetgetinfixinoutleftmutatingnonenonmutatingoperatoroverridepostfixunowned(sale)unowned(unsafe)weakwillset

参考:
oschina 珲少
Swift关键词inout-让值类型以引用方式传递
swift常用关键字

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

推荐阅读更多精彩内容

  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young阅读 3,771评论 1 10
  • 基础部分(The Basics) 当推断浮点数的类型时,Swift 总是会选择Double而不是Float。 结合...
    gamper阅读 1,257评论 0 7
  • 常量与变量使用let来声明常量,使用var来声明变量。声明的同时赋值的话,编译器会自动推断类型。值永远不会被隐式转...
    莫_名阅读 433评论 0 1
  • Hello Word 在屏幕上打印“Hello, world”,可以用一行代码实现: 你不需要为了输入输出或者字符...
    restkuan阅读 3,147评论 0 5
  • 梅 花 一 弄 断 人 肠 梅 花 二 弄 费 思 量 梅 花 三 弄 风 波...
    性本善良阅读 728评论 0 0