喵神swifter學(xué)習(xí)筆記

1、隨機數(shù)

不需要隨機數(shù)種子

arc4random()%N + begin:產(chǎn)生begin~begin+N的隨機數(shù)

arc4random_uniform(endIndex-startIndex)+startIndex:產(chǎn)生startIndex到endIndex的隨機數(shù)

arc4random_uniform(N):產(chǎn)生0~N-1之間的隨機數(shù)

2、自動閉包;??操作符如何實現(xiàn)

1)閉包

閉包標準定義

{[捕獲列表] (參數(shù)) ->返回類型in語句returnxxx}

//自動閉包,閉包標準定義

testClusure { (s, s2) -> String in

return "1"

}

//根據(jù)上下文:推斷類型,推斷類型指的是1)返回類型,2)參數(shù)類型

testClusure() {

s1, s2in

return "123"

}

//單表達式:隱式返回,表達式的值作為返回值

testClusure { s1, s2 in

"asdfasdfadsf"

}

//參數(shù)名稱縮寫

testClusure {

$0 + $1

}

testClusure(clusure: +)

//尾隨閉包省略括號()

testClusure { (s1, s2)in

returns1 + s2

}

2)自動閉包

不接受任何參數(shù)!!

表達式的值,會被返回

//自動閉包

testClusureAuto(adsf:"asdfasdfasdf")

func testClusureAuto(adsf clusure:@autoclosure () -> String) {

}

省略花括號,用一個普通的表達式來代替顯示的閉包

表達式、語句

自動閉包的意義:延遲求值

??

&&

||

()->T

T

如果我們直接使用T,意味著??操作符取值之前,我們就必須準備好一個默認值傳入到這個方法中。

如果這個值是經(jīng)過一系列的復(fù)雜運算,就會造成浪費,因為如果optinal值是有值的,根本就用不上T這個默認值

而是直接返回解包后的值。

這樣的開銷是可以完全避免的,就是將默認值的計算推遲到判斷optional為nil之后

逃逸

@escaping

閉包

值捕獲

引用類型,值類型

let playClosure = {

(child:Child) -> ()? in

child.Pet?.toy?.play()

}

func play() {

}

if let a:() =playClosure(xiaoming) {

}

let playClosure = {

(child:Child) -> String? in

child.Pet?.toy?.play()

}

func play() -> String {

return "adsf"

}

if let a =playClosure(xiaoming) {

}

child.Pet?.toy?.play()單表達式閉包隱式返回,整個表達式的值作為閉包的返回值

就看play的定義了

這樣的調(diào)用將會返回一個()?

其實就是一個可選的空元組:貓神也不是萬能的啊,這都說不明白:“雖然看起來挺奇怪的,但這就是事實”

3、操作符

1、重載操作符

2、聲明一個新的操作符

定義一個操作符的優(yōu)先級

結(jié)合律方式,優(yōu)先級順序

操作符不能定義在局部域中,要求能在全局返回使用你的操作符

adjacent operators are in non-associativeprecedence group tt

adjacent相鄰

associative組合

precedence優(yōu)先級

struct Developer{

static func test() {

let t1 = Developer()

let t2:Developer = "a"

let t3 = "helloooooo"

let _ = t1~=t2~=t3

}

}

//字面量表達

extensionDeveloper:ExpressibleByUnicodeScalarLiteral{

typealias UnicodeScalarLiteralType = String

init(unicodeScalarLiteral value: String) {

logFlag("我就啥也不干")

}

}

//操作符重載

precedencegroup tt {

//指定結(jié)合性

associativity:left

//指定優(yōu)先級

higherThan:MultiplicationPrecedence

}

infix operator ~=:tt

func~=(left:Developer,right:Any)->Developer{

print("我給Developer類實現(xiàn)了一個自定義的操作符:~=,有需要用的嗎?")

return left

}

//不指定優(yōu)先級和結(jié)合性也可以重寫啊

infix operator ~+

func ~+(left:Developer,right:Developer){

print("我就啥也不干,就看看操作符是這些重寫嗎")

}

4、inout

&:

inout原理:inout,修改變量。在函數(shù)內(nèi)部創(chuàng)建了一個新的值,并把這個值賦值給原來的變量

值類型:

inout在函數(shù)內(nèi)部,創(chuàng)建了一個新的值,然后在函數(shù)返回的時候,把這個值符給了給&修飾的變量,

這與引用類型的inout機制是不同的。

如果是引用類型呢??

5、字面量表達

字面量表達-》字面量表達協(xié)議-》協(xié)議規(guī)定了哪些方法??

一個類型支持字面量表達賦值,則需要自定義一個相關(guān)類型的表達協(xié)議,并把這個類型繼承他

自定義一個自己的字面量表達

隱式轉(zhuǎn)換,使用字面量的方式進行

let a = "asdfasdfafsd"http://這就是字符串字面量

let a =

["asdfafsd","asdfasdf"]//數(shù)組字面量

let a =

["a":"asdfasdf","b":"1231321"]//字典字面量

把一個類型,實現(xiàn)ExpressionByBooleanLiteral系列的協(xié)議,這個類就支持字面量表達了

字面量表達很隱蔽的特性。缺點是,沒有辦法對字面量復(fù)制進行跳轉(zhuǎn)。我們不知道這個賦值到底是在哪里實現(xiàn)的

6、下標

重寫下標操作符

7、嵌套

函數(shù)嵌套

8、命名空間

默認是使用自己所在的target的.編譯系統(tǒng)會根據(jù)不同的targe自動加上命名空間。

如果在同一個target里面,如果定義的某個類是相通的,還是會產(chǎn)生沖突

app:

第三方framework:

myframework.myclass

9,typealias

別名

場景1

class df{

}

//typealias dff = df

typealias dff =df

場景2--組合協(xié)議

protocol Pro1{}

protocol Pro2{}

typealias Proall = Pro1 & Pro2

10、associatedtype:關(guān)聯(lián)類型

1)

協(xié)議中聲明一個關(guān)聯(lián)類型,在協(xié)議中規(guī)定的屬性、方法中使用這個關(guān)聯(lián)類型

當某個類、結(jié)構(gòu)體、枚舉約定為繼承這個協(xié)議時,

在實現(xiàn)這個協(xié)議規(guī)定的方法中,可以對協(xié)議規(guī)定的關(guān)聯(lián)類型進行指定,

這樣在實現(xiàn)這些協(xié)議方法、屬性時,不同的類、結(jié)構(gòu)體、枚舉,雖然繼承同樣一個協(xié)議,

但是,操作的結(jié)果就不一樣的,不需要對類型進行is as? as!方法進行類型判斷!

2)有associatedtype的協(xié)議,不能單獨使用

protocol animal can only be used as ageneric constraint

because it has self or associated type

requirements

protocol Animal{

associatedtype F

func eat(food:F)

}

struct Tigger:Animal{

typealias F = Meat

func eat(food: Meat) {

print("老虎吃肉")

}

}

protocol Animal2{

func eatFood()

}

extension Animal2{

func eatFood(){

}

}

struct Chicekent:Animal2{}

struct Dogg:Animal2{}

func isDangerous(animal:Animal2)->Bool {

if animal is Dogg {

return true

}else {

return false

}

}

//func isDangerous(animal:Animal)->Bool {

//if animal is Tiger {

//return true

//} else {

//return false

//}

//}

11,可變參數(shù)

只能有有一個參數(shù)是可變的

可變參數(shù)的類型都是相同的,但是可以用Any

12,init,deinit順序

init先子類,再父類

deinit先子類,再父類

super.init可以不用寫的,系統(tǒng)會自動加上,如果要修改父類的值,則需要顯示調(diào)用super.init,然后在訪問父類的變量,進行修改。

要在init中調(diào)用init,需要在init前面加convenience

父類中帶參數(shù)的init在子類中重載時,子類的這個init實現(xiàn)中系統(tǒng)不會自動加,需要手動添加

父類的便利構(gòu)造器,子類調(diào)用父類便利構(gòu)造器實現(xiàn)的init方法,子類不需要寫便利構(gòu)造器,同樣可以獲得便利構(gòu)造器的使用

13,optional init

求x的y次方pow

14,class,static

1)非class類型,struct,enum:使用static

2)class專門用在class類型中,如果用static,表示不可以重寫

3)協(xié)議中使用static

至于為什么?

class可以重寫,static不可以重寫

struct,enum值類型的數(shù)據(jù)類型中,可變存儲屬性,常量存儲屬性,計算屬性,方法類屬性,類方法都是子類不可以重寫的,因此用static

struct,enum值類型不允許實現(xiàn)子類,就不存在重寫的問題,所用static,表示不可以重寫

struct,enum不允許繼承:inheritancefrom non-protocol type 'StructA1'

協(xié)議中規(guī)定的屬性,方法,也是不可以在子協(xié)議中進行重寫的,因此用static

class類中用class類屬性:只能是計算屬性,可以用class,static

protocol協(xié)議中,加static,類屬性、類方法

struct A1{

func printHello(){}

}

//struct A2:A1 {

//func printHello(){}

//}

class ClassA1{

func printHello(){}

class func printHello2(){}

static func printHello3(){}

static var s1:String = "123"

class var s2:String {get{return "123"}}

static let s3:String = "1212"

}

class ClassB1:ClassA1{

override func printHello(){}

override class func printHello2(){}

//override static func printHello3(){}

}

protocol ProtocolA1 {

static func printHello()

static var s3:String{get}

//class func printHello2()

//protocol協(xié)議,實例屬性可以實現(xiàn)為計算型,也可以實現(xiàn)為存儲型

var s4:String{get}

var s5:String{get set}

var s6:String{get}

}

class ClassA2:ProtocolA1{

static func printHello() {

}

static var s3: String {return "asdfasf"}

var s6: String {return "asdfasd232"}

var s4: String = {return "asdfasdfa"}()

var s5: String = "1234123"

}

15、集合

1)Dictionary,array,set類型都是相同的,或者都為any

2)如何實現(xiàn)一個多類型集合呢?巧用枚舉來實現(xiàn),存儲多種不同類型的值

枚舉關(guān)聯(lián)值

class func testAnyCollection(){

let a =[strOrInt.getInt(123),strOrInt.getStr("asdfa"), strOrInt.getBlock({(hell) in

print(hell)

})]

for i in a {

switch i {

case .getBlock(let a):

a("1341234123")

case .getStr(let s):

print(s)

case .getInt(let n):

print(n)

//case .getIntAndStr(let s, let n):

//print(s)

//print(n)

case .getIntAndStr(let s, 1):

print(s)

case .getIntAndStr(let s, let a):

print(s, a)

}

}

}

enum strOrInt{

case getStr(String)

case getInt(Int)

case getBlock((String)->())

case getIntAndStr(String,Int)

}

16、正則表達式

如何構(gòu)建一個正則表達式工具

這個工具用一個struct來組織

1)提供pattern變量,提供一個初始化方法,提供一個匹配方法

2)更高級一點的方法是:實現(xiàn)一個操作符,

func =~(left:String, right:String) ->Bool {

}

17、模式匹配

switch,for,if,try..catch..,

1)判等

2)判可選類型是否為nil

3)判范圍

底層如何實現(xiàn)的呢?

其實就是系統(tǒng)實現(xiàn)了~=操作符。

18、...和..<

其實這就是range操作符

這個操作符,系統(tǒng)有一系列的操作符范型函數(shù)的定義

...start<=end

..

range操作符返回一個:范型閉開區(qū)間或者范型range

HalfOpenInterval

Range

ClosedInterval

應(yīng)用場景:

1)for語句

2)先創(chuàng)建一個閉開或者range,然后使用閉開或者range的coutains方法,判斷某個字符是否屬于這個閉開區(qū)間。

比如判斷是不是小寫字母

19、.self,和.Type

AnyClass

.Type存放類型的類型

有Int類型:存放的是整形值,String類型:存放的是字符串,AnyObject.Type類型存放的是Anyobject類型

ClassA.self:類型實例

一個存放類型的類型,怎么稱呼他?元類型

意義:

調(diào)用類方法:調(diào)用類方法的時候可以用這個元類型的實例來調(diào)用它的類方法

.self類型實例

.Type類型實例的類型

.self協(xié)議實例

.Protocol協(xié)議類型實例的類型

//協(xié)議元類型,有啥作用呢

let s11:ProtocolA1.Protocol = ProtocolA1.self

//用法1,用模式匹配

//很明顯:系統(tǒng)沒有實現(xiàn)這種類型的模式匹配操作~=,那我們來一個

let e:[Any.Type] =[NSString.self,NSDictionary.self,NSArray.self,ClassA3.self,String.self,(()->()).self]

for i in e {

switch i {

case NSString.self:

print("這里存放了一個nsstring類型,把這個類型存起來了")

case String.self:

print("string類型")

case (()->()).self:

print("得了")

default:

print("asdfa")

}

}

func ~=(left:Any.Type,right:Any.Type)->Bool{

if left == right {

return true

}

return false

}

//用法2,用if語句

let arr:[AnyObject.Type] = [ClassA3.self,ClassA1.self]

for i in arr {

if i is ClassA1.Type {

letd = i as! ClassA1.Type

d.printHello2()

}

if i == ClassA3.self {

let d = i as! ClassA3.Type

d.print2()

}

}

20、Self

copy方法舉例

//定義個一個協(xié)議:使用Self

protocol Copyable{

func copy()->Self

}

class MyClass:Copyable{

func copy()->Self{

let r = type(of:self).init()

return r

}

required init(){

}

}

21、動態(tài)類型

多方法

swift,編譯器編譯的時候,決定使用哪個方法;swift默認情況下,不采用動態(tài)派發(fā)。

方法的調(diào)用在編譯的時候決定。

如果不要系統(tǒng)自動派發(fā),可以修改代碼,用as?類型進行判決,調(diào)用對應(yīng)類型的方法

22、屬性觀察器

1)willset,didset存儲型屬性可以加,計算型屬性不允許加觀察器。

因為計算型屬性,本來就可以監(jiān)控到屬性的改變

2)如果偏要給已有的類型增加觀察器,怎么操作?

用子類來繼承。繼承了以后,給父類的任何屬性:存儲型,計算型都可以加觀察器,我們不用管他是

存儲型還是計算型。

3)唯一注意點是什么:

正因為子類重寫父類的計算型屬性的觀察器,didset方法會先讀oldvalue,這將導(dǎo)致父類的get方法被調(diào)用。

23、什么情況下使用final

1)md5算法、des加密解密的工具類,很穩(wěn)定了,可以加final。

2)某些類似編號的產(chǎn)生方法等對系統(tǒng)的正確運行決定作用的屬性或方法,加final,防止子類重寫時給系統(tǒng)造成錯誤

3)加了final,子類不能去做一些自己可以做的事情,怎么破解呢?

我們可以在final的這個方法中,調(diào)用一個方法,并在當前類定義中實現(xiàn)這個方法,在這個方法斷言,子類必須去重寫。

這樣,就解除了我們在調(diào)用final方法過程中不能做一些自己想做的事情。

class ClassB3:ClassB2{

override func getConfigValue() -> String {

return "come from b3 class !!"

}

}

class ClassB2{

final func printHello(){

print("load begin")

let a = getConfigValue()

print("load end"+a)

}

func getConfigValue()->String{

fatalError("子類必須要實現(xiàn)這個方法")

}

}

24、lazy

延遲屬性、延遲方法

1)延遲,相比于oc,延遲存儲屬性,延遲計算屬性

延遲存儲變量,延遲計算變量

2)如果沒有貓神,確實我僅知道1的應(yīng)用場景

swift提供了幾個全局方法

//序列: lazy方法名,范型列表,參數(shù):范型參數(shù),符合協(xié)議SequenceType的一個實例,返回一個LazySequence范型類實例

func lazy(s:S) ->LazySequence

//無序

func lazy(s:S) ->LazyRandomAccessCollection

//雙向

func lazy(s:S) ->

LazyBidrectionCollection

//前向

func lazy(s:S)->LazyForwardCollection

給一個集合,返回一個集合

這個比較難

arr.lazy.map

25、swift運行時

反射和mirror

class func testRuntime(){

let a = PersonA(name: "asdf", age: 12)

let mirror = Mirror(reflecting: a) // MirrorType

for child in mirror.children {

print(child.label , child.value)

}

}

class PersonA{

var name:String

var age:Int

init(name:String,age:Int){

self.name = name

self.age = age

}

}

應(yīng)用場景:

1)在運行的時候,通過Mirror的手段,了解一個Swift類型的實例的屬性信息

我們可以把某一個swift實例,通過mirror,得到children,

label,value集合值,找到我們要找的目標key value

2)局限:swift的mirror只能讀取,不能修改。我們最好不要在app中用這個mirror,

而是在playground和repl中對類的層次進行探索

26、隱式解包

可選類型

?

!

Optional

1)可選類型,是什么類型??

是結(jié)構(gòu)體,枚舉,類,閉包,元組,函數(shù)?

當然是枚舉

enum Optional {

//啥也沒有

case None

//關(guān)聯(lián)類型:關(guān)聯(lián)一個T類型的實例

case Some(T)

}

2)

多重Optional是個什么鬼?

這樣理解,

var a:String? = nil

let b:String?? = a盒子?盒子?放了一個字符串

let c:String?? = nil盒子?空盒子or不是空盒子

3)Optional Map

extension CollectionType {

//入?yún)ⅲ阂粋€閉包: 1)參數(shù)是采納本身這個協(xié)議的一個element實例2)返回值是返回一個任意類型

//返回值:返回一個任意類型的數(shù)組

publicfunc map (transform:@noescape ((Self.Generator.Element) -> T))-> [T]{

//Swift標準庫具體的實現(xiàn)

}

}

public enum Optinal:_Reflectable,NilLiteralConvertible {

//入?yún)ⅲ阂粋€閉包:1)參數(shù)是一個任意類型,2)返回值是任意類型的這么一個閉包

//返回值:任意類型

publicfunc map(f:@noescape((T)->U))-> U? {

//Swift標準庫實現(xiàn)

}

}

Int?=>Optional

String? =>Optional

Array? => Optional

函數(shù)式編程的思想,他是一種思想,寫一個函數(shù),約定一個規(guī)則,在這個規(guī)則下寫這個函數(shù),不要亂搞。

我們因此又稱他為范式。

函數(shù)式編程的范式又是什么呢?

1,函數(shù)是第一等公民

2,只用表達式,不用語句

表達式:單純的運算過程。總是有返回值

語句:執(zhí)行某種操作,沒有返回值

函數(shù)式編程的出發(fā)點動機,就是處理運算。

3,沒有副作用

函數(shù)內(nèi)部與外部互動,產(chǎn)生表達式運算以外的結(jié)果。

函數(shù)式編程強調(diào):函數(shù)要保持獨立,

所有功能就是返回一個新的值,沒有其他的行為,尤其是不得修改外部變量的值。

4,不修改狀態(tài)

變量往往用來保存“狀態(tài)”,不修改變量,意味著狀態(tài)不能保存在變量中。

函數(shù)式編程使用參數(shù)保存狀態(tài)的一個特例就是遞歸。

5,引用透明

只要傳入什么參數(shù)相同,返回的結(jié)果永遠都是相同

Optional可選實例的map方法

結(jié)合類型的map方法

let arr= [1,2,3,4]

let arr2 = arr.map{$0 * 2}

print(arr2)

let b:Int? = 1

let c = b.map { t in return"12341"}

print(c)

27、協(xié)議擴展

應(yīng)用場景:

1)提供一個協(xié)議方法的默認實現(xiàn),=》變相實現(xiàn)了可選協(xié)議

2)如果一個協(xié)議的擴展中提供了一個默認實現(xiàn),然后這個協(xié)議并沒有對這個默認函數(shù)進行聲明。

繼承這協(xié)議的類的實例調(diào)用這個方法時,還是可以調(diào)這個默認實現(xiàn)的。如果這個類中自己實現(xiàn)了這個協(xié)議方法,他會調(diào)用自己類里面實現(xiàn)的。

這正是按照我們所想的方法執(zhí)行的。

3)擴展一個協(xié)議的時候,加上where限定條件,可以指定1)、繼承這個協(xié)議的2)并且滿足條件的類、結(jié)構(gòu)體、枚舉Self,需要實現(xiàn)這個擴展

中的方法。

28,where在哪里使用

//報錯:where clasuecannot be attached to a protocol declaration

protocol ProtoclA18 where Self:String {

func method2()

}

協(xié)議不能像class一樣在名稱后面加來定義范型,但是可以使用關(guān)聯(lián)類型associated來定義一個引入的范型類型。

如何定義個一個協(xié)議,只能要求被某些特定類來實現(xiàn)呢??

//Perfect

定義一個空協(xié)議,然后擴展這個協(xié)議,在擴展中指定這個協(xié)議,只能由某些特定類型來繼承

protocol ProtocolA18{

}

extension ProtocolA18 whereSelf:ProtocolOther{

func method()

}

@objc protocol ProtocolA18{

}

extension ProtocolA18 whereSelf:ProtocolA19 {

func method2(){}

}

extension ProtocolA18 where Self:ClassTest{

func method3(){}

}

protocol ProtocolA19 {

func method2()

}

@objc protocol ProtocolA17 {

func method()

}

//這個類不繼承那個協(xié)議,交給它所屬的實例類來實現(xiàn)協(xié)議

class ClassA17:ProtocolA18 {

//協(xié)議類型

weakvar protocolObj:ProtocolA18?

//method2, method3都不需要實現(xiàn)。

func method2(){

}

}

class ClassTest:ProtocolA18 {

var a:ClassA17!

func viewDidLoad(){

//let a = ClassA17()

a = ClassA17()

a.protocolObj = self

}

func method() {

print("helloworld")

}

deinit {

logFlag()

}

func method3() {

}

}

//if else

let arr = ["123413","胡asdf","胡阿水淀粉","李思思"]

arr.forEach { (a:String) in

if a.hasPrefix("胡") ,a.characters.count > 4 {

print(a ,"是老師")

}else {

print(a, "是學(xué)生")

}

}

//switch case

arr.forEach { (a) in

switch a {

//這where只能加一個條件啊

case let x where x.hasPrefix("胡"):

print(a ,"是老師")

default:

print(a, "是學(xué)生")

}

}

//for in

for i in arr where i.hasPrefix("胡") {

print(i ,"是老師")

}

//用在協(xié)議擴展里:擴展協(xié)議中,對擴展的協(xié)議增加限定:關(guān)聯(lián)類型繼承某個協(xié)議

let c2 = ClassC2()

let c1 = ClassC1()

c1.printBBB()

//報錯

c2.printBBB()

extension ProtocolC1 whereSelf.TT:Comparable {

func printBBB(){

print("bbb")

}

}

extension ProtocolC1 {

//func printAAA()

func printhello(){

print("擴展協(xié)議,提供了方法的默認實現(xiàn),但是這個方法,并沒有在協(xié)議中定義")

}

}

class ClassC2:ProtocolC1{

var name="asdfasdf"

typealias TT = Any?

func printhello() {

print("AAA")

}

}

class ClassC1:ProtocolC1{

typealias TT = Int

var name = "asdfasf"

func printhello() {

print("我們自己來實現(xiàn)這個協(xié)議,那么擴展協(xié)議中的默認實現(xiàn)的方法還會被調(diào)用嗎")

}

}

29、使用枚舉而不是class或者struct來定義一個鏈表

不加indirect,編譯報錯!

嵌套定義枚舉的時候,必須加上indirect關(guān)鍵字

class func testIndirectEnum(){

let a1 = E.n(1)

let a2 = E.n(3)

let a3 = E.add(a1, a2)

let r = E.eval(l: a3)

print(r)

}

indirect enum E {

case n(Int)

case add(E, E)

//需要一個嵌套函數(shù)

static func eval(l:E)->Int{

switch l {

case .n(let t):

return t

case .add(let l1, let l2):

returneval(l: l1) + eval(l: l2)

}

}

}

class C1{

classfunc a() {

let c = E.add(E.add(E.n(1), E.n(3)), E.n(3))

let d = E.eval(l: c)

print(d)

let _ = LinkedList.node(1, LinkedList.node(2, LinkedList.empty))

}

}

30, Swift -》》selector

2種表現(xiàn)形式Selector and#selector

selector是一個關(guān)鍵字,返回一個類型

-(void)callMe{}

SEL method = @selector(callMe)

-(void)callMe:(id)obj{}

SEL method2 = @selector(callMe:)

swift=>

定義一個selector

掛一個方法:@objc

class AA {

@objc func printhello(){}

func print(){

#selecotor(printhello)

}

}

@objc(BB)

class BB {

func printHello()

func print(){

#selecotor(printhello)

}

}

執(zhí)行一個selector

Selector("method")警告:不要顯示調(diào)用,需要改為#selector關(guān)鍵字

#selector(method(parm1:param2:))

#selector(method(param1:))

#selector(method2)

如果同名子的方法只有一個,沒有參數(shù)、標簽不同的同名函數(shù),則可以省略參數(shù)列表

func method2(a:String,b:String){}

func method(param1:String,param2:String){}

func method(param1:String){}

#selector(method2)//這種調(diào)用也是可以的。因為他的方法沒有同名

但是可以將方法進行強制轉(zhuǎn)換

#selector(method as (string,string)->())

#selector(method as (string)->())

31,實例方法的動態(tài)調(diào)用

實例方法

實例屬性不可以

class ClassA10{

func printHello(){

logFlag("hello")

}

}

//字面量取值

f = ClassA10.pringHello

{

//參數(shù)ClassA10

(obj:ClassA10) in

//返回值:是一個函數(shù)

return obj.printHello

}

f1(ClassA10())()

原理:

(Xcode8_swift3_iOS8_10.ClassA10)->()->()

(Xcode8_swift3_iOS8_10.ClassA10)->(String)->()

(Xcode8_swift3_iOS8_10.ClassA10)->(String,String)->(String)

(Xcode8_swift3_iOS8_10.ClassA10)->(String)->(String)

柯里化方法

(String)->()-()

//動態(tài)調(diào)用

let f1 = ClassA10.printHello

f1(ClassA10())()

//ClassA10.printHello的字面量表達

let a = {

(obj:ClassA10) -> ()->() in

return obj.printHello

}

a(ClassA10())()

32,單例

實例屬性:存儲型常量,存儲型變量,計算型變量

類屬性:存儲型常量,存儲型變量,計算型變量

由于swift1.2之前版本的屬性特性,類屬性不能有存儲型變量、存儲型常量。所以單例的實現(xiàn)方式就要借助于全局變量,

然后在計算型變量中,返回這個全局變量。

那么1.2開始以后,就會有更簡單的單例實現(xiàn)版本了。

class Manager{

//存儲型常量來保存單例

static let shared = Manager()

private init(){}

}

33,條件編譯

1)條件的語法怎么寫?

還是c語言語法格式的寫法,只不過對條件加了指定

#if XXX

#elseif XXX

#else

#endif

//省略else,elseif

#if XXX

#endif

//省略elseif

#if XXXX

#else XXX

#endif

2)什么情況用到條件編譯?

指定的條件如下:

os()

os(macOS) os(iOS) os(tvOS) os(watchOS)os(Linux)

os(FreeBSD) os(Windows) os(Android)

arch()

arch(x86_64)

arch(arm)

arch(arm64)

arch(i386)

swift()

swift(1.2)

swift(2.3)

swift(3.0)

#if FREE_VERSION

#else

#endif

build settings->swift compiler -》custom flags-》other swift

flags加上-D FREE_VERSION

34、Xcode標記

// MARK:

// MARK:-

// TODO:

// FIXME:

oc中有的:

#warning

#param

35、@UIApplicationMain

生成模版代碼

36、

動態(tài)派發(fā)

@objc修飾

@dynamic

oc中的協(xié)議里存在關(guān)鍵字:

@optional

//swift不支持可選協(xié)議

protocol OptionalProtocol{

optional func optionalMethod()

}

//支持可選協(xié)議,

@objc protocol OptionalProtocol {

@objc optional func optionalMethod()

}

使用@objc修飾的協(xié)議,只能被class實現(xiàn),不能被struct,enum實現(xiàn)

37、內(nèi)存管理

引用計數(shù)

arc

當實例的引用為nil的時候,系統(tǒng)就會釋放內(nèi)存

什么時候?qū)嵗囊脼閚il?

1)超過作用域,2)手動設(shè)置為nil

產(chǎn)生循環(huán)引用的條件:

1)引用類型實例產(chǎn)生循環(huán)引用

2)閉包引起循環(huán)應(yīng)用,其實閉包也是一個引用類型。還是可以歸屬為1

一個class有一個閉包屬性。閉包屬性里面又使用了self,就產(chǎn)生循環(huán)

在方法內(nèi)部初始化的生成的對象在被返回后別人還能使用,而不是立即釋放掉

延遲釋放

func autoreleasepool(code:()->())

每次超過作用域后,自動內(nèi)存管理都會為我們處理好內(nèi)存相關(guān)的事情???

//每次獲得一個產(chǎn)生一個data

func loadBigData() {

if let path =nsbundle.mainbundle().pathForResource("big",ofType:"jpg") {

for i in 1...10000 {

autoreleasepool{

//方法1:

let data =nsdata.datawithContentsOfFile(path,options:nil,error:nil)

//方法2:工廠方法-》》初始化方法

let data =NSData(contentsOfFile:path)

nsthread.sleepfortimeInterval(0.5)

}

}

}

}

整個線程一個自動釋放池,每個主runloop結(jié)束時候進行drain操作。

drain的作用:

1)把池子里面的引用類型的實例,實例的引用為nil的時候,或者說引用計數(shù)為0的實例,進行釋放。

所以,即使一個實例沒有強引用了,或者引用計數(shù)為0了,只要釋放池沒有執(zhí)行drain操作,他就不會得到釋放

2)把引用計數(shù)-1

值類型

傳遞、賦值=》復(fù)制

引用類型

傳遞、賦值=》引用對象的一個指向

String,Dictionary,Array,值類型,少量數(shù)據(jù)用此。如果數(shù)據(jù)大,就用cocoa中的NSDictionary,NSArray

值類型:內(nèi)存是在棧上。

引用類型:堆上。

String or NSString ?

//String

let a = "ABCDE"

let range =a.characters.index(a.startIndex, offsetBy:1)..

let b = a.replacingCharacters(in: range,with: "A")

print(b)

//NSString

let c = (a asNSString).replacingCharacters(in: NSMakeRange(1, 4), with: "A")

print(c)

38、Swift和C

Swift和C指針

Swift如何處理指針?

C的識別特點就是指針

OC -》C?

Swift-》C?

Unsafe開頭的,

void * -》UnsafePoint

const Type * ->UnsafePointer

Type * ->UnsafeMutablePointer

unsafeBitCast(CFArrayGetValueAtIndex(arr,0),to:CFString.self)

C開頭的;

int -》CInt

array -> CFArray

string -> CFString

COpaquePointer

UnsafeMutablePointer并不會自動進行內(nèi)存管理,因此把某一個pointer = nil,并不能自動釋放內(nèi)存

deinitialize-》釋放指針指向的內(nèi)存的對象

deallocate -》釋放指針自己本身

指向函數(shù)的指針-》C打交道,1)直接用閉包2)@convention(c)標注

allocate

initialize

deinitialize

deallocate

var a:UnsafeMutablePointer!

a =UnsafeMutablePointer.allocate(capacity: 1)

a.initialize(to: ClassA12())

print(a.pointee.name)

a.deinitialize()

a.deallocate(capacity: 1)

a = nil

opaquepointer

39、怎么封裝一個漂亮的gcd調(diào)用?

嵌套函數(shù)好復(fù)雜!!!

40、Swift類型操作

1)獲取類型的類型

xx.self和Type

類型,XXX.self

類型的類型,XXX.Type

AnyClass = AnyObject.Type

2)獲取實例的類型

實例=》》》》類型

type(of:obj)

object_getClass(obj)

3)Self

class MyClass:Copyable {

funccopy()->Self {

letr = type(of:self).init()

returnr

}

requiredinit(){

}

}

4)swift類型判斷

isKindOfClass:屬于某個類或者繼承自這個類

isMemberOfClass:屬于某個類

適用于NSObject類型或其子類型

isKind

isMemeber

用is:is相當于原來的isKindOfClass,可以檢查屬于某個類或者繼承自這個類

他不僅可以用class引用類型上,還可以用于struct,enum類型

在范型中使用類型判斷:提前約束是何種類型,在編譯期間就可以確定類型要求

41、花括號的演變

1、

c語言中利用{}

1)代碼塊,看著清晰一點

2)利用作用域,釋放內(nèi)存

2、

swift 2.0以前

用尾隨閉包

func do(b:()-()){

b()

}

do{

。。。。。

}

3、

那么2.0以后呢?

就用do,加入了do關(guān)鍵字,捕獲異常的作用區(qū)域

do {

}

4、

使用匿名閉包----用閉包賦初始化值

let label:UILabel = {return UILabel()}()

42、

swift判等

NSObject子類:看是否重寫了父類isEqual方法,默認的是用父類的isEqual方法判等

Swift類型,不繼承NSObject的類:判等==,需要把類繼承Equatable協(xié)議,然后實現(xiàn)操作符==方法,否則編譯報錯

如果是Swift的原生類型,如String,Dictionary,系統(tǒng)自動實現(xiàn)了Equtable協(xié)議了,我們不需要自己去重寫啥的。

let a1 = ClassA13(name: "huchu")

let a2 = ClassA13(name:"study")

if a1 == a2 {

print("重寫的判斷生效了")

}

let a3 = ClassA14(name: "huchu")

let a4 = ClassA14(name:"study")

//報錯,無法編譯:沒有重寫判斷操作符==

if a3 == a4 {

print("無法判等的")

}

let a5 = ClassA15(name: "huchu")

let a6 = ClassA15(name: "study")

if a5 == a6 {

print("NSObject的子類,默認調(diào)用NSObject父類的判等方法:isEqual")

}

let a7 = ClassA16(name: "huchu")

let a8 = ClassA16(name: "study")

if a7 == a8 {

}

class ClassA13:Equatable {

var name:String

init(name:String) {

self.name = name

}

public static func ==(lhs: ClassA13, rhs: ClassA13) -> Bool {

return true

}

}

class ClassA14 {

var name:String

init(name:String) {

self.name = name

}

}

class ClassA15:NSObject {

var name:String

init(name:String) {

self.name = name

}

}

//Redundant conformance of classa16 toprotocol equatable

class ClassA16:NSObject,Equatable {

var name:String

init(name:String) {

self.name = name

}

override func isEqual(_ object: Any?) -> Bool {

print("NSObject的子類,默認調(diào)用NSObject父類的判等方法:isEqual")

if object is ClassA16 {

let j = object as! ClassA16

return j.name == self.name

}

return false

}

public static func ==(lhs: ClassA16 , rhs: ClassA16) -> Bool {

print("NSObject的子類,優(yōu)先看有沒有實現(xiàn)Equatable協(xié)議方法==判等操作符:優(yōu)先調(diào)用了")

if lhs.name == rhs.name {

return true

}

return false

}

}

43、swift日志輸出

print

NSLog

占位:

%d,%@,%02d,%f

let t = String(format: "%.02f",b)

print(t)

print("\\(t)")

let t2 = String(format: "%.02f",1.234567)

print(t2)

print("\\(t2)")

let t3 = String(format: "%.02f",1234567)

print(t3)

print("\\(t3)")

NSLog("%.02f", 1234567)

NSLog("%.02f", 1234567.1)

輸出如下

1.23

1.23

1.23

1.23

0.00

0.00

0.00

1234567.10

在oc中輸出

NSLog(@"%.02f", 1234567);

0.00

44、Options選項

原來的選項Option值-》滿足OptionSetType協(xié)議的struct類型,以及一組靜態(tài)的get屬性。

想一想,why?

OptionSetType是實現(xiàn)了SetAlgebraType的

Algebra:代數(shù)學(xué)

set algebra:集合代數(shù)

用集合來代替邏輯運算符&、|位運算

//這里太復(fù)雜:OptionSet

struct SexOptions : OptionSet {

//可以省略

typealias RawValue = UInt

let rawValue:UInt

static let none = SexOptions(rawValue: 0)

static let optionMale = SexOptions(rawValue: 1)

static let optionFemale = SexOptions(rawValue: 1<<1)

static let optionGmale = SexOptions(rawValue: 33)

}

public protocol OptionSet : SetAlgebra,RawRepresentable {

}

public protocol RawRepresentable {

}

public protocol SetAlgebra : Equatable,ExpressibleByArrayLiteral {

}

public protocol Equatable {}

public protocol ExpressibleByArrayLiteral{}

字面量。

45、列舉

enumerate:列舉元素的同時,也需要下標

// OC的用法

func addf() {

var arr:NSArray = [1,2,3,4,5,6]

var r = 0

//ambiguous use of enumerateObjects為什么報錯?

arr.enumerateObjects { (value, idx, stop) -> Void in

r += num as! Int

if idx == 2 {

stop.pointee = true

}

}

print(r)

}

//Swift

var arr = [1,2,3,4,5,6]

func addfSwift() {

var r = 0

//沒有要求在閉包中操作,我還想測試一下循環(huán)引用的

for (idx, value) in arr.enumerated() {

r += value

if idx == 2 {

break

}

}

print(r)

}

let arr = [(1,2),(3,4)]

for i in arr {

print(i.0, i.1)

}

for i in arr.enumerated() {

print(i.0,i.1)

}

for (a,b) in arr.enumerated() {

print(a, b.0,b.1)

}

輸出如下:

1 2

3 4

0 (1, 2)

1 (3, 4)

0 1 2

1 3 4

EnumerateGenerator:包含元素索引下標,以及元素本身的多元組

EnumeratedSequence>

EnumeratedSequence分析:

EnumeratedSequence是一個結(jié)構(gòu)體,范型結(jié)構(gòu)體,范型要求為符合協(xié)議--Sequece協(xié)議

并且自身也符合協(xié)議--Sequece協(xié)議

怎么就跟元組掛上鉤了呢???

難道又是模式匹配嗎,又或是字面量表達

字面量表達-》字面量表達協(xié)議-》協(xié)議規(guī)定了哪些方法??

switch,for,if,try..catch..,

1)判等

2)判可選類型是否為nil

3)判范圍

底層如何實現(xiàn)的呢?

其實就是系統(tǒng)實現(xiàn)了~=操作符。

[(1,2),(12,312),(1234,1234)]

確實是啊!!

public static func ~=(pattern:CountableClosedRange, value: Bound) -> Bool

Sequece協(xié)議規(guī)定了一個~=模式匹配的方法

EnumeratedSequence<[(Int,Int)]>

EnumeratedSequece<[Int]>

46、通過類型獲取對應(yīng)的編碼?這又是個什么鬼

OC中的用法:

@encode

Swift中的用法:

Metatype

不能獲取任意類型的類型編碼了。

但是在Cocoa中,即繼承自NSObject類型的類,可以通過NSValue的objcType來獲取對應(yīng)值的類型指針。

如果需要獲取Swift類型的類型編碼,可以將他轉(zhuǎn)換為NSNumber,NSNbumer是NSValue的子類,然后再獲取類型

objCType

let t1 = 1 as NSNumber

print(String(validatingUTF8: t1.objCType))

let t2 = NSValue(cgPoint:CGPoint(x: 3, y:3))

print(String(validatingUTF8: t2.objCType))

let t3 =NSValue(cgAffineTransform:.identity)

print(String(validatingUTF8:t3.objCType))

輸出如下:

Optional("q")

Optional("{CGPoint=dd}")

Optional("{CGAffineTransform=dddddd}")

//這有個毛的意思?

Swift語言參考

類型、

Swift類型:string,dictionry,array,Int,Double。。。。

Swift中保留的C類型:CInt,CFArray....

Swift中保留的OC類型:NSDictionary...

函數(shù)類型,閉包類型,協(xié)議類型。。。。

表達式、

3+4, let a = 3 , somefunciton()

語句、

if else,

while,

for,

do{try...}catch模式1{}catch模式2{}catch {}

switch-case

模式匹配、

i in 1...10,

case模式

where Self:SomeProtocol

where i > 10

聲明、

特性、

范型

47、@asmname使用c的標準庫

48、weak

1)協(xié)議前面加上@objc

2)協(xié)議后面加上class

applied:應(yīng)用

weak may only be applied to classand class-bound protocol types

protocol ProtocolA17 {

func method()

}

protocol ProtcolA18 where

//這個類不繼承那個協(xié)議,交給它所屬的實例類來實現(xiàn)協(xié)議

class ClassA17{

//協(xié)議類型,這是一個成員屬性,這個屬性必須要求實現(xiàn)協(xié)議

weak var protocolObj:ProtocolA17?

}

class ClassTest:ProtocolA17 {

var a:ClassA17!

func viewDidLoad(){

//let a = ClassA17()

a = ClassA17()

a.protocolObj = self

}

func method() {

print("helloworld")

}

deinit {

logFlag()

}

}

swift中的protocol協(xié)議:

值類型,引用類型都可以繼承某一個協(xié)議,struct,enum雖然可以用protocol,但是不存在引用計數(shù)這樣的內(nèi)存管理問題,所以就無需用到weak

@objc protocol ProtocolA17 {

func method()

}

protocol ProtocolA20:class{

func method()

}

//這個類不繼承那個協(xié)議,交給它所屬的實例類來實現(xiàn)協(xié)議

class ClassA17:ProtocolA18 {

//協(xié)議類型

weak var protocolObj:ProtocolA18?

//method2, method3都不需要實現(xiàn)。

func method2(){

}

}

class ClassA20{

weak var obj:ProtocolA20?

}

class ClassTest:ProtocolA18,ProtocolA20 {

var a:ClassA17!

var b:ClassA20!

func viewDidLoad(){

//let a = ClassA17()

a = ClassA17()

a.protocolObj = self

b = ClassA20()

b.obj = self

}

func method() {

print("helloworld")

}

deinit {

logFlag()

}

func method3() {

}

}

49、關(guān)聯(lián)對象

public struct UnsafeRawPointer :Strideable, Hashable {

}

static var key:Void?

&key=>>UnsafeRawPointer這樣就可以轉(zhuǎn)了嗎?

//key這個參數(shù),為什么是要傳入一個可變的指針

public func objc_getAssociatedObject(_object: Any!, _ key: UnsafeRawPointer!) -> Any!

public func objc_setAssociatedObject(_object: Any!, _ key: UnsafeRawPointer!, _ value: Any!, _ policy: objc_AssociationPolicy)

extension ClassA20{

static var title:()?

static var key2 = "adfs"

static let key3 = "123123"

var title:String{

get{

return objc_getAssociatedObject(self, &ClassA20.title) as! String

}

set{

objc_setAssociatedObject(self, &ClassA20.title, newValue,objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)

}

}

var title2:String{

get{

return objc_getAssociatedObject(self, &ClassA20.key2) as! String

}

set{

objc_setAssociatedObject(self, &ClassA20.key2, newValue,objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)

}

}

//cannot pas immutable value as inout argument:key3 is a let constant

var title3:String{

get{

return objc_getAssociatedObject(self, &ClassA20.key3) as! String

}

set{

objc_setAssociatedObject(self, &ClassA20.key3, newValue,objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)

}

}

}

let a = ClassA20()

print(ClassA20.key2)

print(ClassA20.title)

a.title = "hello"

a.title2 = "world"

print(ClassA20.key2)

print(ClassA20.title)

輸出如下

adfs

nil

adfs

nil

50、線程同步

objc_sync_enter

objc_sync_exit

怎么在swift中在封裝一下,更加好用?

class func lockSafe(lock:Any,l:()->()){

objc_sync_enter(lock)

l()

objc_sync_enter(lock)

}

class func testLock(){

let obj = ClassA20()

objc_sync_enter(obj)

print(obj)

objc_sync_exit(obj)

Test.lockSafe(lock: obj) {

print(obj)

}

}

59、CF*****Swift自帶的CF系列,內(nèi)存管理自動管理的。不需要release等

60、

swift命令

repl:swift repl環(huán)境read eval printloop

可以進行簡單的交互式編程,每輸入一句語句,就立即執(zhí)行到我們眼前

xcrun swift

swift

如何寫一個swift腳本,就像shell腳本一樣?

vi 1.swift

#!/usr/bin/env swift

print("hello")

chmod +x 1.swift

./1.swift

swift文件如何編譯

vi 2.swift

print("hello")

swiftc 2.swift 3.swift other.swift....

./main

swift生成匯編代碼

vi 3.swift

print("hello")

swiftc -O 3.swift -o 3.asm

61、print和debugPrint

結(jié)論,

1)實現(xiàn)了custom和customdebug其中的任何一個,print,debugPring打印的都是一樣的結(jié)果

2)如果都實現(xiàn)了,pring調(diào)用custom,debugPrint調(diào)用customDebug

3)如果都沒有實現(xiàn),那就只能系統(tǒng)默認打一個ClassX.self的類型了

print是執(zhí)行CustomStringConvertible協(xié)議規(guī)定的方法

printDebug是執(zhí)行CustomDebugStringConvertible協(xié)議規(guī)定的方法

對于一個普通的對象,只能打印出它的類型。

struct可以打印出成員的名稱和值

如何實現(xiàn)一個CustomStringConvertible協(xié)議?

extension ClassA20:CustomStringConvertible{

var description: String {

return "helll"

}

}

extensionClassA20:CustomDebugStringConvertible {

var debugDescription: String {

return "world"

}

}

1)實現(xiàn)CustomStringConvertible,不實現(xiàn)CustomDebugStringConvertible:

helll

helll

2)不實現(xiàn)CustomStringConvertible,實現(xiàn)CustomDebugStringConvertible:

world

world

3)實現(xiàn)CustomStringConvertible,實現(xiàn)CustomDebugStringConvertible:

helll

world

4)不實現(xiàn)CustomStringConvertible,不實現(xiàn)CustomDebugStringConvertible:

Xcode8_swift3_ios8_10.ClassA20

Xcode8_swift3_ios8_10.ClassA20

print(ClassA20.self)

debugPrint(ClassA20.self)

輸出

ClassA20

Xcode8_swift3_ios8_10.ClassA20

62、斷言

斷言:它是一個開發(fā)時的特性,只有在debug編譯的時候有效。而在運行時是不能被編譯執(zhí)行的。

所以,在代碼發(fā)布的時候,我們不用刻意去將這些斷言手動清理掉。

這是默認的斷言特性

target, build settings swift

compiler-custom flags中

other swift flags中添加

-assert-config Debug來強制啟用斷言,

-assert-config Release來強制禁用斷言

貌似不管用啊!!!

在release中,如何強制終止程序呢,我們最好不要修改斷言的配置選項。

而是使用另外一個函數(shù)。

fatalError

調(diào)用這個方法,不需要返回值

func asd()->Int{

fatalError("asdf")

}

斷言只會在Debug環(huán)境中有效,而在Release編譯中所有的斷言都將被禁用。在遇到確實因為輸入的錯誤無法使程序繼續(xù)運行的時候,我們一般考慮以產(chǎn)生致命錯誤(fatalError)的方式來終止程序。

63、面向協(xié)議編程和模擬的抽象函數(shù)的方式

64、錯誤和異常

異常

1)為什么要用異常?

調(diào)用某些方法,我們開發(fā)時候很容易忽略的時候,就用異常,避免我們忽略nserror

同步調(diào)用中用異常

異步調(diào)用不用異常,用error

2)怎樣使用異常

do try catch

try?

try!

throws

實現(xiàn)一個繼承Error枚舉的枚舉類。拋出這個新的枚舉類型。

class func someMethodTrhows2 (b:Bool)throws-> Int? {

if b {

throw myError.value

}

return nil

}

//返回的是nil還能執(zhí)行if。因為是optional套一個optional

if let a = try?someMethodTrhows2(b: false){

print(a)

} else {

print("err")

}

rethrows :

在方法中加rethrows,表示這個方法的型參列表中,有一個參數(shù),也可能拋出異常,即是一個能拋出異常的閉包類型或者函數(shù)類型,

然后呢,這個方法本身自己不會拋出任何異常,除了型參的方法被調(diào)用拋出異常外。

如果這個方法,仍然用throws來修飾:表明,型參閉包被調(diào)用時,拋出異常;自己的處理過程中,也允許拋出異常。

凡是調(diào)用了拋出異常的方法,在調(diào)用它時,都必須加上try的形式來調(diào)用。

這表明啊:加rethrows的方法,只要它的參數(shù),我們給他傳遞進去的時候,雖然在型參中我們聲明了這個函數(shù)可能拋出異常,但是

我們在實參的定義中,如果作為實參的閉包,并沒有拋出異常,既沒有寫throw Error.XXX時,我們是可以不用try來調(diào)用的!!

既可以接受普通函數(shù),也可以接受一個普通函數(shù),雖然這個參數(shù)是throw的

//報錯

someMethodTrhows1(b: true)

//報錯

someMethodTrhows3(b:true) { (b) -> Int in

if b {throw myError.value}

}

//不報錯,可以這樣用

someMethodTrhows3(b: true) { (b) -> Intin

return 1

}

//必須要加try調(diào)用

try!someMethodTrhows4(b: true) { (b) ->Int in

return 100

}

a function declared rethrows may only throwif its parameter does

class func someMethodTrhows3(b:Bool,f:(Bool)throws->Int) rethrows-> Int {

let _ = try f(true)

//a function declared rethrows may only throw if its parameter does

//if b {

//throw myError.value

//}

return 100

}

class func someMethodTrhows4(b:Bool,f:(Bool)throws->Int) throws-> Int {

let _ = try f(true)

if b {

throw myError.value

}

return 100

}

let _ = try?someMethodTrhows3(b: true, f: {(b:Bool) -> Int in

if b {

throw myError.value

}

return 100

})

let _ = try?someMethodTrhows4(b: true, f: {(b:Bool) -> Int in

if b {

throw myError.value

}

return 100

})

65、framework orextension

框架or擴展?

1)單獨為swift制作框架-》專門生成框架的項目

將整個框架項目,包括源代碼,以項目依賴的方式添加到自己的項目中,并一起編譯使用。

shift+cmd+i release版本

cmd+b debug版本

2)制作的框架只能嵌入到自己的app中

3)用純Swift制作可用的第三方庫

66、字符串=》使用原始值為String的enum類

然后通過擴展類的extension,來引用這些enum。

R.swift SwiftGen,掃描所有文件-》提取字符串-》自動生成enum或者struct文件

67、

@dynamic:告訴編譯器,我們不會再編譯時就確定這個屬性的行為實現(xiàn)

不需要在編譯期間對這個屬性的getter或setter做檢查和關(guān)心。

表示我們將在運行時來提供這個屬性的存取方法,如果在運行時,沒有對這個屬性提供存取方法,就會crash

CoreDataModel,

使用xcode工具,自動生成NSManagedObject子類

Swift,不保證一切都走動態(tài)派發(fā)。

CoreData專用:@NSManaged

68、KVO、KVC

動態(tài)派發(fā)

觀察的對象標記為dynamic

在oc中,KVC的屬性,進行監(jiān)聽。而現(xiàn)在,需要NSObject的,dynamic修飾的,可以監(jiān)聽

Observable-Swift

范型、閉包、屬性觀察器-》》》KVO

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,488評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,034評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,327評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,554評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,337評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,883評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,114評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,625評論 1 332
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,555評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,737評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 43,973評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,615評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,343評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,699評論 2 370

推薦閱讀更多精彩內(nèi)容