亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Swift > 正文

升級到Swift 4.0可能遇到的坑總結

2020-03-09 17:43:32
字體:
來源:轉載
供稿:網友

前言

swift/37122.html">swift4.0已經出來一段時間,之前已經給大家總結介紹了關于swift4的新特性,那么本文就來介紹下當swift升級到swift4在使用中會遇到哪些問題呢?下面話不多說了,來一起看看詳細的介紹吧。

升級Swift4.0

  • 并不是所有庫都能做到及時支持Swift4.0,更何況是在現在連Xcode9也還是beta的狀態
  • 所以我們僅能做到將自己的業務代碼(主工程代碼)部分升級到Swift4.0,然后同時保留各種pod庫在Swift3.2版本。
  • 沒辦法,誰叫Swift4.0也還無法做到API兼容呢(但愿能在Swift5之前實現吧)。
  • 至于我說的同時使用兩個版本的Swift,這是沒問題的,Xcode9支持在項目中同時使用Swift3.2和Swift4.0。

一. 修改Swift版本

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

swift,4,升級,swift4.0

2. 修改pod庫

在Podfile文件的最下方加入如下代碼,指定pod庫的Swift版本為3.2(這樣會使得所有的第三方pod庫的Swift版本都為3.2)

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

二. 主工程中的代碼修改

1. 列舉一下Swift3.2到Swift4.0的改變(只是我項目中遇到的):

1). Swift4.0中對于擴展的屬性(包括實例屬性、static屬性、class屬性),都只能使用get方法,不可使用set方法

2). Swift4.0中不再允許復寫擴展中的方法(包括實例方法、static方法、class方法)

      比如:自定義的協議方法在extension中實現,若某個類遵循了該協議,其子類便不能重寫該協議方法

      解決的方法是: 在每個需要該協議的類里面都重新遵循該協議,實現協議方法

      個人想到的辦法,不知道有沒有其他解決辦法可以提供一下

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

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

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

NSFontAttributeName --- .font //或者NSAttributedStringKey.fontNSForegroundColorAttributeName --- .foregroundColor//NSAttributedStringKey.foregroundColorNSStrikethroughStyleAttributeName --- .strikethroughStyle//NSAttributedStringKey.strikethroughStyle//字符串類型的,添加rawValueNSAttributedStringKey.font.rawValue//等等等等..........//大部分類似以下,涉及富文本的方法均已改為了NSAttributedStringKey類型addAttributes(_ attrs: [NSAttributedStringKey : Any] = [:], range: NSRange)

三. 項目中遇到的一些的報錯問題

3-1. "Closure cannot implicitly capture a mutating self parameter"錯誤

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

struct RecordModel { /// 定義一個閉包 var action: (() -> ())? var height = 10  self.action = {   self.height = 20   //Closure cannot implicitly capture a mutating self parameter報錯 }}

++并且由于RecordModel的類型是struct,我們也沒發在action閉包里添加截獲列表。那么是不是就必須使用class了?答案是否定的。有兩種方式可以解決這個問題。++

方案一:為closure增加一個inout類型的參數

struct RecordModel { /// 定義一個閉包 var action: ((_ inSelf: inout RecordModel) -> ())? var height = 10  self.action = { (inSelf) in  inSelf.height = 20  }}

根據inout類型的說明,我們知道,實際上這相當于增加了一個隱藏的臨時變量,self被復制,然后在closure(閉包)中使用,完成后,再復制回self。也就是說,這個方法有額外的內存開銷。如果是struct較大的情形,這么做并不劃算。

方案二:使用UnsafeMutablePointer<Pointee>

==這次采用直接指針的方式對于struct來進行操作,采用指針的好處是self不會被多次復制,性能較高。缺點是你需要自行確定你的代碼的安全。==

struct RecordModel { /// 定義一個閉包 var action: (() -> ())? var height = 10  let selfPointer = UnsafeMutablePointer(&self) self.action = {   selfPointer.pointee.height = 20    }}

結論

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

注意

這里可以記一下指針和swift變量之間的關系:

  • UnsafePointer對應let
  • UnsafeMutablePointer對應var
  • AutoreleasingUnsafeMutablePointer對應unowned UnsafeMutablePointer,用于inout的參數類型
  • UnsafeRawPointer對應let Any,raw系列都是對應相應的Any類型
  • UnsafeBufferPointer是non-owning的類型(unowned),用于collection的elements, buffer系列均如此

3-2. Declarations from extensions cannot be overridden yet 錯誤

==這個錯誤大致是因為,協議方法是在extension里面的,不能被重寫==

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

小編想到的解決辦法就是在每一個需要此協議的類里面,重新遵循代理,實現該協議方法

3-3. "Method 'initialize()' defines Objective-C class method 'initialize', which is not permitted by Swift"

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

方法交叉(Method Swizzling)

有時為了方便,也有可能是解決某些框架內的 bug,或者別無他法時,需要修改一個已經存在類的方法的行為。方法交叉可以讓你交換兩個方法的實現,相當于是用你寫的方法來重載原有方法,并且還能夠是原有方法的行為保持不變。

extension UIViewController { public override class func initialize() {//此處報錯   //此處省略100行代碼   }}

initialize該方法已經被Swift4.0廢棄

在Swift3.0還勉強可以使用,但是會有警告;但是在4.0已經被完全廢棄

==替代方法:==

在 app delegate 中實現方法交叉

像上面通過類擴展進行方法交叉,而是簡單地在 app delegate 的 application(_:didFinishLaunchingWithOptions:) 方法調用時調用該方法

extension UIViewController { public override class func initializeOnceMethod() {   //此處省略100行代碼   }}//在AppDelegate的方法中調用:func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool { //此處省略100行代碼 UIViewController.initializeOnceMethod()}

3-4. 'dispatch_once' is unavailable in Swift: Use lazily initialized globals instead

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

extension UITableView { struct once{  static var onceTaken:Int = 0 } dispatch_once(&once.onceTaken) { () -> Void in //在這里dispatch_once就會報錯  //此處省略1000000行代碼  }}

解決方法: 通過給DispatchQueue添加擴展實現

extension DispatchQueue { private static var _onceTracker = [String]() public class func once(token: String, block: () -> ()) {  objc_sync_enter(self)  defer {   objc_sync_exit(self)  }  if _onceTracker.contains(token) {   return  }  _onceTracker.append(token)  block() }  func async(block: @escaping ()->()) {  self.async(execute: block) }  func after(time: DispatchTime, block: @escaping ()->()) {  self.asyncAfter(deadline: time, execute: block) }}

使用字符串token作為once的ID,執行once的時候加了一個鎖,避免多線程下的token判斷不準確的問題。
使用的時候可以傳token

 DispatchQueue.once(token: "tableViewOnce") {  print( "Do This Once!" )  }

或者使用UUID也可以:

private let _onceToken = NSUUID().uuidString DispatchQueue.once(token: _onceToken) {  print( "Do This Once!" ) }

四、swift3.2升級到swift4.0 掃碼不走回調方法

xcode升級到9.0 swift改到swift4.0之后掃碼一直不走回調 ,研究了好長時間,發現蘋果把掃碼的代理方法的參數變了之前的方法

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!)func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!)

這是之前swift3.2的代理方法,swift4.0之后不會走這兩個代理方法,原因是現在代理方法不一樣了

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection)func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection)

swift4.0的兩個代理方法對比之前的3.2方法,可以發現現在方法的參數變了

將之前的兩個方法的參數改好,掃碼就可以正常用了

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。


注:相關教程知識閱讀請移步到swift教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久女人电视剧免费播放下载| 国产精品综合久久久| 日韩精品亚洲视频| 日本韩国在线不卡| 日韩av片永久免费网站| 精品自在线视频| 亚洲一区二区三区在线免费观看| 日韩av在线导航| 91av视频导航| 一本色道久久88综合日韩精品| 97超视频免费观看| 欧美日韩中文字幕综合视频| 啊v视频在线一区二区三区| 色与欲影视天天看综合网| 亚洲激情中文字幕| 成人免费自拍视频| 国产亚洲人成a一在线v站| 欧美精品一区二区三区国产精品| 亚洲国产精品视频在线观看| 欧美精品电影免费在线观看| 欧美精品久久久久久久久| 97久久精品国产| 永久免费看mv网站入口亚洲| 国产亚洲视频在线观看| 亚洲第一网站男人都懂| 成人国产精品色哟哟| 国产亚洲视频在线观看| 久久精品青青大伊人av| 久久久精品一区二区| 久久久国产精品视频| 亚洲精品有码在线| 欧美国产日韩在线| 青青草精品毛片| 亚洲精品一区二三区不卡| 亚洲一区二区少妇| 久久精品国产69国产精品亚洲| 亚洲美女av在线播放| 国产欧美一区二区三区视频| 成人福利免费观看| 宅男66日本亚洲欧美视频| 2023亚洲男人天堂| 成人av资源在线播放| 亚洲第一福利网站| 欧美超级乱淫片喷水| 国产精品美女免费看| 国产午夜精品麻豆| 亚洲欧美自拍一区| 亚洲精品久久久久久久久久久久| 亚洲电影免费在线观看| 日韩精品一区二区视频| 欧美激情一区二区三区成人| 91精品视频在线播放| 日韩欧美亚洲一二三区| 久久久999国产精品| 欧美日韩成人在线视频| 不卡伊人av在线播放| 久久国产精品99国产精| 91系列在线观看| 国产福利精品在线| 亚洲国产一区二区三区在线观看| 亚洲成人精品视频在线观看| www.欧美三级电影.com| 亚洲男人天堂手机在线| 日韩男女性生活视频| 97香蕉超级碰碰久久免费软件| 亚洲自拍av在线| 国产精品青草久久久久福利99| 亚洲精品成人久久久| 欧美老女人xx| 97视频免费观看| 91国自产精品中文字幕亚洲| 97视频在线观看免费| 欧美第一黄网免费网站| 少妇精69xxtheporn| 欧洲s码亚洲m码精品一区| 欧美日韩国内自拍| 成人av资源在线播放| 欧美在线亚洲在线| 亚洲国产精品免费| 亚洲成人动漫在线播放| 亚洲天堂成人在线| 俺去啦;欧美日韩| 性色av一区二区三区免费| 欧美另类极品videosbestfree| 亚洲2020天天堂在线观看| 日韩av网站在线| 日本91av在线播放| 国产在线视频不卡| 久久精品国产亚洲精品2020| 高清欧美性猛交xxxx黑人猛交| 国产精品无av码在线观看| 91精品视频免费看| 亚洲成人在线视频播放| 91久久国产精品91久久性色| 日本三级久久久| 国产精品美女主播| 亚洲免费小视频| 亚洲激情在线视频| 亚洲第一免费播放区| 久久天堂av综合合色| 欧洲成人在线视频| 亚洲欧美一区二区三区在线| 亚洲色图美腿丝袜| 亚洲欧美国产高清va在线播| 中文字幕亚洲天堂| 国产精品69久久久久| 欧美极品第一页| 成人免费看片视频| 日韩**中文字幕毛片| 亚洲天堂男人天堂女人天堂| 91免费在线视频| 91免费国产网站| 欧洲成人午夜免费大片| 中文字幕亚洲综合久久筱田步美| 26uuu另类亚洲欧美日本一| 91超碰中文字幕久久精品| 国产欧美va欧美va香蕉在线| 亚洲黄色av女优在线观看| 欧洲成人免费aa| 在线国产精品视频| 国产精品久久久久久久电影| 日韩在线观看电影| 中文字幕日韩欧美在线视频| 亚洲另类欧美自拍| 久久影视免费观看| 国产一区二区欧美日韩| 不卡av日日日| 国产97在线|日韩| 国产精品综合不卡av| 伦伦影院午夜日韩欧美限制| 亚洲日韩中文字幕| 日韩电影中文字幕av| 欧美尺度大的性做爰视频| 一区二区三区美女xx视频| 久久成人人人人精品欧| 色天天综合狠狠色| 亚洲一区二区三区乱码aⅴ| 日本电影亚洲天堂| 亚洲一区二区久久久久久久| 欧美极品少妇全裸体| 欧美成人午夜激情视频| 亚洲精品免费在线视频| 欧美激情日韩图片| 日韩精品视频免费在线观看| 日韩中文字幕在线| 欧美精品在线观看91| 日韩av电影在线免费播放| 国产精品女人久久久久久| 国产一区二区三区日韩欧美| 国产精品欧美一区二区三区奶水| 日韩av电影免费观看高清| 亚洲午夜色婷婷在线| 成人免费视频在线观看超级碰| 国产日韩欧美在线播放| 97人人做人人爱| 九九热99久久久国产盗摄| 久久青草福利网站| 国产噜噜噜噜噜久久久久久久久| 国产一区二中文字幕在线看| 日韩av手机在线| 久久久久久久一区二区三区| 亚洲va国产va天堂va久久| 性欧美长视频免费观看不卡| 亚洲综合大片69999|