chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

“踩坑”經(jīng)驗分享:Swift語言落地實踐

OSC開源社區(qū) ? 來源:OSC開源社區(qū) ? 2023-12-28 17:37 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

導讀introduction Swift 是一種適用于iOS/macOS應用開發(fā)、服務器端的編程語言。自2014年蘋果發(fā)布 Swift 語言以來,Swift5 實現(xiàn)了 ABI 穩(wěn)定性、Module 穩(wěn)定性和Library Evolution,與Objective-C(下文簡稱“OC”)相比,Swift 在開發(fā)效率、安全、編譯優(yōu)化、運行性能和內存管理方面具有顯著優(yōu)勢。(官方博客:https://www.swift.org/about/

百度App 已在工程和環(huán)境上支持 Swift 開發(fā),百度搜索大前端團隊負責搜索服務的穩(wěn)定落地,我們積極探索 Swift的應用,希望能大幅提升開發(fā)效率和靈活性、提升端用戶的搜索體驗。然而,在實施過程中可能會遇到各種問題,例如代碼陳舊且不支持Swift,人員對Swift掌握不夠熟練、意識不足,協(xié)作方對Swift的支持不足等。

對于其他語言來說,Swift相對年輕,我們在實踐過程中整理一些常見問題及其解決方法,希望能幫助讀者更順利地使用Swift進行編程,提高研發(fā)效率。

GEEK TALK

01

Swift 適用場景

在決定是否引入Swift前,我們需要判斷場景是否適合。通常情況下,可以用OC的場景均適合使用Swift,但也有一些不太適合直接替換的場景,需要慎重,比如:

1、涉及OC動態(tài)性,頻繁在runtime時操作屬性和方法;

2、核心基礎功能,出現(xiàn)問題影響面較大的邏輯;

3、調用C++(目前Swift不能直接調用C++);

4、繼承不支持Swift組件的類。

此外,對使用OC比較久遠的工程,使用Swift前也應注意:

1、能在工程環(huán)境和單獨模塊上支持Swift;

2、模塊較多的工程,可以內外OC和Swift混編;

3、為了避免Swift Waring帶來的潛在問題,可以把SWIFT_TREAT_WARNINGS_AS_ERRORS設置為YES,這樣警告會作為錯誤,輔助程序員更好的規(guī)范代碼;

4、模塊Module化后,要注意維護 umbrella header 中的公開頭文件。

注:本文中的“組件”均指代工程中的“Target”。

GEEK TALK

02

Swift的基本用法

2.1 Swift 的字符串為什么這么難用?

如:字符串不能通過索引取字符
  • 原因:Swift認為字符串是由一個個字形群集 (grapheme clusters)組成的,字形群集的大小不固定所以不能用整數(shù)去索引 (字形群集其實就是Swift中的Character(字符)類)。

  • 解決方案:如要通過下標取字符可以為String添加擴展在下標subscript實現(xiàn)通過傳入Int索引,在subscript轉為String.index獲取對應字符的方式。

2.2 try try? try! 的區(qū)別

當你進行文件操作時,可能會遇到需要使用try、try?和try!的情況。它們在異常處理方面有所不同。

1、使用try時,如果出現(xiàn)異常,程序會進入異常處理流程,你可以在catch語句塊中處理這個異常。

2、使用try?時,如果發(fā)生異常,它不會進入異常處理流程,而是返回一個可選值類型。也就是說,如果出現(xiàn)異常,它將返回nil。

3、使用try!時,它不允許異常繼續(xù)傳播。一旦出現(xiàn)異常,程序會立即停止執(zhí)行。

因此,在文件操作中,你可以根據(jù)需要選擇合適的異常處理方式。在百度App中一般推薦使用try?。

2.3public 和 open 的區(qū)別

在Swift語言中,public和open都是用于在模塊中聲明需要對外界暴露的函數(shù)的關鍵字,但它們在繼承和公開程度上有所不同。

1、public關鍵字修飾的類在模塊外部無法被繼承。這意味著,如果其他模塊試圖繼承這個類,編譯器會報錯。這樣的限制可以保護類的完整性,但也可能限制了其在其他模塊中的可重用性。

2、open關鍵字則允許任意繼承。如果一個類被open關鍵字修飾,那么其他模塊中的類可以自由地繼承這個類,不受任何限制。這樣的公開程度使得open關鍵字修飾的類在模塊間的重用性和擴展性更加靈活。

從公開程度上來說,public的限制比open更嚴格,所以可以說public < open,即public的公開程度比open要低。

2.4 解析JSON情況

在Swift中解析JSON的情況,如果自行將JSON轉換為字典,需要涉及到類型判斷、轉換等操作,代碼比較復雜。這時可以使用第三方庫SwiftyJSON、ObjectMapper或者系統(tǒng)庫JSONEncoder來簡化操作,提高開發(fā)效率。

2.5 UIView子類必須添加init?(coder decoder: NSCoder)的原因

1、這是NSCoding protocol定義的,遵守了NSCoding protocol的所有類必須繼承。只是有的情況會隱式繼承,而有的情況下需要顯示實現(xiàn)。

2、當我們在子類定義了指定初始化器(包括自定義和重寫父類指定初始化器),那么必須顯示實現(xiàn)required init?(coder aDecoder: NSCoder),而其他情況下則會隱式繼承,我們可以不用理會。

3、當我們使用storyboard實現(xiàn)界面的時候,程序會調用這個初始化器。

4、注意要去掉fatalError,fatalError的意思是無條件停止執(zhí)行并打印。

2.6 Swift類和子類的初始化

Swift的類和子類初始化涉及到兩個關鍵階段。首先,確保所有的存儲屬性被賦予初始值,然后,在實例準備使用之前,可以自定義存儲屬性的值。為了確保這兩個階段成功,實施了四步安全檢查,詳細如下:

1、在完成本類所有存儲屬性賦值之后,指定構造器才能向上代理到父類的構造器。

2、在為繼承的屬性設置新值之前,指定構造器必須向上代理調用父類構造器。

3、便利構造器必須先調用其他構造器,再為任意屬性(包括所有同類中定義的)賦新值。

4、在第一階段構造完成之前,構造器不能調用任何實例方法,不能讀取任何實例屬性的值,不能引用self作為一個值。

總之,類初始化必須完成的一個任務就是讓所有的存儲屬性都有初始值(optional 除外)。如果父類有指定初始化,子類必須也有指定初始化,并且必須調用父類的其中一個指定初始化(如果是必須初始化,就是重載),并遵循兩段式初始化的規(guī)則。一個便利初始化必須調用同一類中的初始化方法(可以是另一個便利初始化,也可以是指定初始化),但最終一定會調用到一個指定初始化。便利初始化不遵循兩段式初始化的規(guī)則,不能被子類調用或者重載。

GEEK TALK

03

OC與Swift的互相調用及跳轉

3.1 組件內Swift文件調用公開OC頭文件

  • 將公開OC頭文件(如:xyz.h)添加到組件(如:ABC)umbrella header中(如:#import);

  • Swift文件中直接調用公開OC頭文件內容。

3.2組件內Swift文件調用非公開(私有)的OC文件

組件應該盡可能少的公開暴露頭文件,但Swift和OC混編不可避免使用OC非公開頭文件,因此我們可以采取以下措施:將Framework 中將私有頭文件聲明為一個私有 module(modulemap內聲明),由組件內的 Swift 源碼 import 該私有 module 即可。

1、創(chuàng)建Private.modulemap文件,以NewModule做為組件名為例,可以命名為NewModule.private.modulemap,內容為下,module后面加_Private

  • 羅列頭文件的形式

framework module NewModule_Private {
  header "xxxxx.h"
}
  • 使用根頭文件的形式,添加頭文件NewModule_Private.h

framework module NewModule_Private {
  umbrella header "NewModule_Private.h"


  export *
  module * { export * }
}

2、在組件build settings中配置MODULEMAP_PRIVATE_FILE路徑,MODULEMAP_PRIVATE_FILE='NewModule.private.modulemap';百度App中在NewModule.boxspec中如下代碼設置路徑;

s.xcconfig = {
    'MODULEMAP_PRIVATE_FILE' => '${BOX_ROOT}/NewModule.private.modulemap'
}

3、將NewModule.private.modulemap添加到工程目錄;百度App中在NewModule.boxspec中如下代碼設置路徑;

s.refer_files = [
      "NewModule.private.modulemap",
]

4、將xxxxx.h設置為Private header,百度App中在NewModule.boxspec中如下代碼設置xxxxx.h到Private header

s.private_headers = [
    "Sources/xxxxx.h"
  ]

5、調用方式

import NewModule_Private
let objectX = xxxxx()
print(objectX)
注意:
  • 添加的Private頭文件可能存在傳遞頭文件的情況,即import其他頭文件,也需要將傳遞的頭文件添加到NewModule_Private中,同時import需要使用尖括號;

  • Private Header也會暴露在framework中,所以可以約定外部組件使用Public Header,而避免使用Private Header,因為隨著業(yè)務發(fā)展和Swift&OC混編,Private Header是不穩(wěn)定的。

3.3組件內OC文件如何調用Swift文件?

  • Swift 類需要繼承 NSObject,方法前面加上@objc 標識,并且是 public 或者 open 的;

  • 引入方式 #import"

3.4OC中的向前聲明,被Swift文件引用該組件會報錯

如error:cannotfindprotocoldefinitionfor'xxxProtocol'
  • 原因:此報錯在OC中是代碼警告,百度App中默認情況Swift中SWIFT_TREAT_WARNINGS_AS_ERRORS 設置為 YES,導致OC中的Warning視為Error;

  • 解決方案:三選一

1、暫時設置 SWIFT_TREAT_WARNINGS_AS_ERRORS 為 NO

2、import xxxProtocol 不要向前聲明

3、使用 pragma 忽略警告

3.8Swift怎么用OC定義的宏?

  • 在Swift中,能直接使用定義為常量的宏,不能使用帶有方法調用的宏,也不能使用靜態(tài)常量。

下面這種定義為常量的宏可以使用
#define APP_LANGUAGE_EN @"en" 
#define kNavigationBarHeight 44.0


下面帶有方法調用的宏不可以使用
#define kScreenHeight [[UIScreen mainScreen] bounds].size.height
#define kScreenWidth [[UIScreen mainScreen] bounds].size.width


下面帶有靜態(tài)常量swift不能使用,可以改成宏
static NSString *const StopTabRefreshNotifyNameHtml = @"TabRefreshNotifyNameHtml";

3.6Swift與OC泛型的混編

  • 在我分們基礎框架中,有一個使用了OC泛型的類,如:

@interface BBAXYZ<T> : NSObject <BBAXYZEventProtocol>  
@property (nonatomic, weak) T page;  
@end

這個泛型的使用導致無法使用Swift來繼承和開發(fā)BBAXYZ的子類。然而,這個基礎框架是業(yè)務的核心部分,因此,我們需要在未來支持Swift的開發(fā)。

  • 經(jīng)過仔細觀察和分析,我們發(fā)現(xiàn)泛型主要被用于指定page屬性的類型。因此,我們可以考慮去掉泛型,改為提供一個返回適當類型的方法。這樣,我們就可以在Swift中順利地繼承和使用這個基礎框架。修改后的代碼如下:

@interface BBAXYZ : NSObject <BBAXYZEventProtocol>  
- (id)page;  
@end

然后,我們可以創(chuàng)建一個OC類來實現(xiàn)這個基礎框架,并讓所有的子類繼承這個OC類并實現(xiàn) page 方法,以返回適當類型的對象。這樣,我們就可以在Swift中順利地繼承和使用這個基礎框架。

例如:

@interface BBAABC : BBAXYZ  
- (UIViewController *)page; 
@end

需要注意的是,雖然這樣的修改增加了輕量級的中間OC類,但它仍然實現(xiàn)了Swift與OC的混編,并允許我們在Swift中開發(fā)新的子類。這種方式既保證了代碼的兼容性,又使得我們可以繼續(xù)利用OC的優(yōu)點。

  • 使用方式

class BBAEFG: BBAABC {
    
}

3.7Swift調用OC接口,OC的nullability標注使用時的注意事項

問題場景:

1、OC 接口定義為 nonnull,swfit 調用時正常是當做不可選類型使用,這時如果 OC 接口不規(guī)范返回 nil,則出現(xiàn)運行時崩潰。

2、OC 接口未定義 nonnull 或 nullable,在這種情況下,編譯器會將 OC 的指針類型當成是隱式解析可選類型(例如 String!)導入到 Swift 中。swift 調用時,OC接口如果返回 nil,將會因為隱式解析一個為 nil 的可選值導致運行時崩潰。

解決方式:

1、Swift 調用 OC 接口時,如果 OC 的接口聲明為 nonnull 或未指定 nullability 時,只有明確 OC 接口不為空的情況下才可調用

2、在 OC 環(huán)境下,將 nil 賦值給 nonnull 指針也沒有關系,編譯器只會產(chǎn)生警告。這就需要程序員按規(guī)范編寫 OC 代碼,正確使用 nullability 標注,并增加運行時判空的斷言,以支持向后兼容。

GEEK TALK

04

其他常見問題

4.1 Xcode編譯只提示編譯錯誤,提示信息非常少

  • 原因:使用Swift語言開發(fā)的組件,依賴了不支持Module化的組件,導致組件都能編譯成功,但整個工程卻編譯失敗了;

  • 解決方案:二選一

1、檢查并保障所有依賴的組件都已經(jīng)Module化了,如配置build settings;

2、在組件中新增Swift文件(空文件也行)。

4.2 由于組件開啟了Library Evolution 導致的編譯報錯

錯誤顯示:@objc' instance method in extension of subclass of 'xxxxx' requires iOS 13.0.0

這是由于組件開啟了Library Evolution導致,開關BUILD_LIBRARY_FOR_DISTRIBUTION 控制的。

一個庫開啟了Library Evolution,在依賴鏈下游的庫中將:

1、對它的類實現(xiàn) @objc 子類。

2、對它的類使用 extension 實現(xiàn) @objc 的方法(這在 UIKit 的 protocol 中經(jīng)常會遇到)。

3、對它的類實現(xiàn)子類,并添加 @objc 方法,且方法中使用父類的類型作為參數(shù)。

這些功能是實現(xiàn)的局限。估計是需要在 Swift 運行時有一些對應的更改,所以只在 swift 5.1 (iOS 13)運行時里才可以運行。

除此之外,還會有一些編譯時沒有報錯,但運行時 crash 或結果不正確的情況。

百度App中默認開啟Library Evolution,一個組件關閉Library Evolution會導致二進制存在不兼容的情況,暫時無解決方案。

4.3 暴露的Private頭文件如果使用雙引號import,會報警告,需要修改為尖括號

如果使用import ,Project下其他Target就引用不到了,如百度App中Debug模塊引用此Private頭文件時,會報錯 not found with include, use "quotes" instead。
  • 原因:這是由于其他Target對主模塊引用時默認是從當前項目下引用頭文件,而尖括號方式從系統(tǒng)庫或用戶庫中引用;

  • 決方案:其他Target將Private Header 配置到其 HEADER_SEARCH_PATHS,使用雙引號和尖括號均可。

GEEK TALK

05

總結

以上是我們在Swift開發(fā)過程中所遇到的一些常見問題及其相應的解決方案。然而,隨著我們不斷深入Swift開發(fā)這片浩渺的海洋,更多獨特的問題將會逐漸浮現(xiàn)。我們會持續(xù)將這些新問題以及其對應的解決方案整理并發(fā)布出來,為廣大的開發(fā)者們提供有價值的參考。歡迎大家留言探討。


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 模塊
    +關注

    關注

    7

    文章

    2788

    瀏覽量

    50421
  • SWIFT
    +關注

    關注

    0

    文章

    116

    瀏覽量

    24357
  • 編程語言
    +關注

    關注

    10

    文章

    1956

    瀏覽量

    36675

原文標題:“踩坑”經(jīng)驗分享:Swift語言落地實踐

文章出處:【微信號:OSC開源社區(qū),微信公眾號:OSC開源社區(qū)】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    PLC工業(yè)智能網(wǎng)關:功能解析、場景落地與選型避攻略

    如何避免選型?本文從技術原理、核心價值、典型場景、避指南四大維度,結合真實案例與行業(yè)趨勢,為您徹底拆解PLC工業(yè)智能網(wǎng)關的“真面目”。
    的頭像 發(fā)表于 07-16 13:21 ?48次閱讀
    PLC工業(yè)智能網(wǎng)關:功能解析、場景<b class='flag-5'>落地</b>與選型避<b class='flag-5'>坑</b>攻略

    使用Word/Excel管理需求的10個痛點及解決方案Perforce ALM

    還在用Word/Excel做需求管理?10個“翻車信號”,都是小伙伴們過的~來看看你過哪些?是不是也該升級到更專業(yè)的ALM工具了~
    的頭像 發(fā)表于 07-10 15:59 ?139次閱讀
    使用Word/Excel管理需求的10個痛點及解決方案Perforce ALM

    2025年G口大帶寬服務器選購指南:避這3點,省下50%成本!

    面對市場上琳瑯滿目的服務器產(chǎn)品,如何避免、實現(xiàn)成本與性能的平衡,成為企業(yè)和個人用戶關注的焦點。本文將從配置需求、避要點、成本控制三大維度,為您提供一份客觀、簡潔的2025年G口大帶寬服務器選購指南。
    的頭像 發(fā)表于 07-10 10:17 ?347次閱讀

    研華工業(yè)AI Agent的發(fā)展態(tài)勢及實踐思考

    工業(yè) 4.0 風起云涌之際,AI Agent 產(chǎn)業(yè)化落地成為各界競逐焦點。研華科技憑借深厚的行業(yè)積淀,勇于創(chuàng)新、積極探索,在企業(yè)級工業(yè) AI Agent 方面積累了扎實的實踐經(jīng)驗。本期訪談邀請到研華
    的頭像 發(fā)表于 06-23 09:31 ?336次閱讀

    鴻蒙5開發(fā)寶藏案例分享---折疊屏開發(fā)實踐

    APP的圖片放大限制、視頻類APP的懸停控制欄 節(jié)省試錯成本 :官方已驗證的方案避免 設計規(guī)范內置 :UX標準直接融入代碼邏輯 跨設備覆蓋 :一套代碼兼容手機/折疊屏/平板/PC ?? 避提示
    發(fā)表于 06-12 11:44

    必看!15個C語言常見陷阱及避指南

    ? C語言雖強大,但隱藏的“”也不少!稍不留神就會導致程序崩潰、數(shù)據(jù)異常。本文整理15個高頻陷阱,助你寫出更穩(wěn)健的代碼! ? 陷阱1:運算符優(yōu)先級混淆? 問題:運算符優(yōu)先級不同可能導致計算順序錯誤
    的頭像 發(fā)表于 03-16 12:10 ?624次閱讀

    手機喇叭氣密性檢測儀選購攻略,避免!

    參差不齊,質量也良莠不齊。本文將為讀者提供一些選購氣密性檢測儀的攻略,幫助企業(yè)在選擇設備時避免。首先,明確檢測需求是選購氣密性檢測儀的前提。企業(yè)需要根據(jù)自身的生產(chǎn)規(guī)
    的頭像 發(fā)表于 02-05 17:04 ?624次閱讀
    手機喇叭氣密性檢測儀選購攻略,避免<b class='flag-5'>踩</b><b class='flag-5'>坑</b>!

    串口設計如何避免?看這篇!

    本文將以Air700ECQ/EAQ/EMQ為例,帶你從硬件設計的角度,一起來了解串口設計中的一些關鍵注意點;軟件開發(fā)或者AT設置方面不做深入探討。 ? 一、串口相關管腳 Air700ECQ/EAQ/EMQ系列模組支持2個串口,分別是: 主串口MAIN_UART 調試串口DBG_UART 對應的管腳如下: ? 注:MAIN_DTR,MAIN_RI管腳嚴格意義來說,并不能歸為串口功能;MAIN_DTR、MAIN_RI是獨立的控制功能管腳。 二、串口功能描述 模組的AT指令控制,數(shù)據(jù)傳輸都是通過主串口來實現(xiàn)。注意,即使采用二次開發(fā)方
    的頭像 發(fā)表于 12-26 11:45 ?585次閱讀
    串口設計如何避免<b class='flag-5'>踩</b><b class='flag-5'>坑</b>?看這篇!

    又給項目埋雷,RS485自動收發(fā)電路設計

    前言 這個文章的題目有點騙眼球的感覺,其實是自己過大坑,很是痛恨這個電路,希望大家以后不要了。工程師要畫這個電路時,網(wǎng)上一搜,不經(jīng)深入分析就拿來用,給項目埋了炸彈。 RS485自動收發(fā)電路 因為
    的頭像 發(fā)表于 12-06 09:59 ?1447次閱讀
    <b class='flag-5'>踩</b><b class='flag-5'>坑</b>又給項目埋雷,RS485自動收發(fā)電路設計

    TPSM843620 SWIFT?降壓評估模塊

    電子發(fā)燒友網(wǎng)站提供《TPSM843620 SWIFT?降壓評估模塊.pdf》資料免費下載
    發(fā)表于 12-05 14:05 ?0次下載
    TPSM843620 <b class='flag-5'>SWIFT</b>?降壓評估模塊

    ADC高速采樣電路設計詳解之STM32

    一、過程 最近用STM32F334做數(shù)字電源,用到了高速ADC采集電壓電流。設計的參考電壓VREF為3.3V,輸入信號經(jīng)運放跟隨后直接接入單片機的采樣通道。一開始測試一切正常,但隨著輸入信號
    的頭像 發(fā)表于 12-02 09:27 ?2898次閱讀
    ADC高速采樣電路設計詳解之STM32<b class='flag-5'>踩</b><b class='flag-5'>坑</b>

    在學習go語言的過程過的

    作為一個5年的phper,這兩年公司和個人都在順應技術趨勢,新項目慢慢從php轉向了go語言,從2021年到現(xiàn)在,筆者手上也先后開發(fā)了兩個go項目。在學習go語言的過程中也學習并總結了一些相關的東西,這篇文章就分享下自己過的一
    的頭像 發(fā)表于 11-11 09:22 ?472次閱讀

    Swift 6.0引領編程語言新趨勢

    近日,蘋果公司公布了一系列重磅消息:推出iOS/iPadOS 18和macOS 15 Sequoia等操作系統(tǒng)更新,以及Swift編程語言的全新版本——Swift 6.0。此番升級重點關注編程安全性、并發(fā)處理能力的提升,并大幅擴
    的頭像 發(fā)表于 09-20 15:57 ?782次閱讀

    【RA-Eco-RA0E1-32PIN-V1.0開發(fā)板試用】+ 應用遇到的

    。 新建了個工程編譯不過。索性卸載了e2studio 重新下載了setup_fsp_v5_5_0_e2s_v2024-07。 了好幾個,終于要上岸了。原來后面還有。 系統(tǒng)環(huán)境
    發(fā)表于 09-03 22:27

    蘋果推出全新開源Swift軟件包

    七月三十一日,蘋果企業(yè)總部對外正式發(fā)表公告,宣布昨日(即七月二十九日)成功推出全新的開源 Swift 軟件包—— (喚名為 swift-homomorphic-encryption)。此舉旨在為 Swift 編程
    的頭像 發(fā)表于 07-31 15:17 ?834次閱讀