公升級Swift4 0遇到的坑

2021-08-08 03:19:04 字數 3094 閱讀 2820

1. 如下圖指定主工程的swift版本為4.0

xcode圖示.png

2. 修改pod庫

post_install do |installer|

installer.pods_project.targets.each do |target|

target.build_configurations.each do |config|

config.build_settings['swift_version'] = '3.2'

end

endend

3). swift3使用#selector指定的方法,只有當方法許可權為private時需要加@objc修飾符,現在swift4.0全都要加@objc修飾符

4). 自定義的protocol協議中,有optional修飾的非必須實現的方法,需要用@objc修飾

5). 字型方面的一些重新命名

nsfontattributename --- .font 

//或者nsattributedstringkey.font

nsforegroundcolorattributename --- .foregroundcolor

nsstrikethroughstyleattributename --- .strikethroughstyle

//字串型別的,新增rawvalue

nsattributedstringkey.font.rawvalue

//等等等等..........

//大部分類似以下,涉及富文字的方法均已改為了nsattributedstringkey型別

addattributes(_ attrs: [nsattributedstringkey : any] = [:], range: nsrange)

在struct中,如果我們在閉包中使用self,就會得到closure cannot implicitly capture a mutating self parameter的錯誤提示。比如:

struct recordmodel 

}

++並且由於recordmodel的型別是struct,我們也沒發在action閉包裡新增截獲列表。那麼是不是就必須使用class了?答案是否定的。有兩種方式可以解決這個問題。++
方案一:為closure增加乙個inout型別的引數
struct recordmodel 

}

根據inout型別的說明,我們知道,實際上這相當於增加了乙個隱藏的臨時變數,self被複製,然後在closure(閉包)中使用,完成後,再複製回self。也就是說,這個方法有額外的記憶體開銷。如果是struct較大的情形,這麼做並不划算。

方案二:使用unsafemutablepointer
struct recordmodel 

}

結論

==closure cannot implicitly capture a mutating self parameter錯誤的原因是在進出closure(閉包)之後,self的一致性沒辦法得到保證,所以編譯器預設不允許在struct的closure(閉包)中使用self。如果我們確定這麼做是安全的,就可以通過上面的兩種方式解決這個問題。其中,方法二的效能更好一些。==

注意

這裡可以記一下指標和swift變數之間的關係:
==這個錯誤大致是因為,協議方法是在extension裡面的,不能被重寫==

解決辦法:(僅供參考,如有更好的建議還望多多指教)

==報錯原因: 在於已經廢棄的initialize方法,示例如下==

extension uiviewcontroller 

}

==替代方法:==

extension uiviewcontroller 

} //此處省略100行**

uiviewcontroller.initializeoncemethod()

}

報錯原因: dispatch_once在swift4.0也已經被廢棄

extension uitableview 

dispatch_once(&once.oncetaken)

}

解決方法: 通過給dispatchqueue新增擴充套件實現
extension dispatchqueue 

if _oncetracker.contains(token)

block()

}func async(block: @escaping ()->())

func after(time: dispatchtime, block: @escaping ()->())

}

使用字串token作為once的id,執行once的時候加了乙個鎖,避免多執行緒下的token判斷不準確的問題。

使用的時候可以傳token

dispatchqueue.once(token: "tableviewonce")
或者使用uuid也可以:

private let _oncetoken = nsuuid().uuidstring

dispatchqueue.once(token: _oncetoken)

Swift4 0 基礎部分

翻譯能力有限,如有不對的地方,還請見諒!希望對swift的學習者有所幫助 swift是一門新的程式語言,用於ios,macos,watchos以及tvos系統平台上應用程式的開發。儘管如此,如果有c和objective c開發經驗的話,那麼對於swift的許多部分,你將並不陌生。c和objectiv...

Swift 4 0 巨集定義

swift中並沒有加入巨集系統,c語言使用 define定義的基本常量在匯入swift時被swift編譯自動轉為swfit語言的全域性變數。但複雜的巨集定義不能被swift轉換。swift中類似巨集定義,可以單獨建立乙個類,如const.swift,在此類中宣告一些常量。例如 螢幕的寬 let sc...

Swift 4 0 陣列 Array 學習

定義陣列常量 常量只有讀操作 let array1 int 11,55,5 let array2 11,55,5 定義陣列變數var array int 這是我最喜歡的 var array0 int 10,20,30 初始化並賦值 var array1 int array var array2 ar...