Swift小結(jié)

//TODO: 用于標(biāo)記未完成的任務(wù)
// FIXNE: 用于標(biāo)記待修復(fù)的問題
//#warning("todo") 警告

條件編譯

//操作系統(tǒng)
#if os(macOS) || os(iOS)
//CPU架構(gòu)
#elseif arch(x86_64) || arch(arm64)
//swift版本
#elseif swift(<5) && swift(>=3)
//模擬器
#elseif targetEnvironment(simulator)
//可以導(dǎo)入某模塊
#elseif canImport(Foundation)
#else
#endif
強(qiáng)制斷言.png
#if DEBUG
DEBUG 模式
#else
release 模式
#endif

如果需要自己自定義編譯器模式 那么可以
第一種方法

WeChat0515ae36c50635b683ea74b2c317dff1.png

在DEBUG 后面加空格再加上自己的編譯器模式
第二種方法

WeChatd1616ca286b55d8900a2cfbd09956e69.png

在里面填寫-D 自己的自定義編譯器模式

打印

func log<T>(_ msg: T,
            file: NSString = #file,
            line: Int = #line,
            fn: String = #function) {
    
    #if DEBUG
    let prefix = "\(file.lastPathComponent)_\(line)_\(fn):"
    print(prefix, msg)
    #endif
}

系統(tǒng)版本檢測

if #available(iOS 10,macOS 10.12, *){
    //對與ios平臺 只在ios10以及以上版本執(zhí)行
    //對于macOS平臺 只在macOS 10.12及以上版本執(zhí)行
    //最后的* 表示在其他所有平臺都執(zhí)行
}

API可用性

struct Student {
    //study_不可用 改名為study
    @available(*,unavailable,renamed: "study")
    func study_() {
        
    }
    func study() {
        
    }
    @available(iOS, deprecated: 11)
    //macOS 的10.12開始 這個(gè)run方法不可用
    @available(macOS, deprecated: 10.12)
    func run() {
        
    }
}

var stu = Student()
stu.run()
錯(cuò)誤.png

ios程序入口

1.在AppDelegate上面默認(rèn)有個(gè)@UIApplicationMain標(biāo)記 表示
  編譯器自動(dòng)生成入口代碼(main函數(shù)代碼) 自動(dòng)設(shè)置AppDelegate為App的代理
2.也可以刪除@UIApplicationMain 自定義入口代碼 新建一個(gè)main.swift文件
import Foundation
import UIKit

class MyApplication: UIApplication {
    
}

UIApplicationMain(CommandLine.argc,
                  CommandLine.unsafeArgv,
                  NSStringFromClass(MyApplication.self),
                  NSStringFromClass(AppDelegate.self))

Swift調(diào)用OC

- 新建一個(gè)橋接頭文件 文件名格式默認(rèn)為 {targetName}-Bridging-Header.h
- 在相應(yīng)的位置寫入橋接頭文件的位置
寫入橋接頭文件的位置.png

如果C語言暴露給Swift的函數(shù)跟Swift的函數(shù)沖突了 可以在swift中使用@_silgen_name 修改C函數(shù)名

@_silgen_name("sum")
func swift_sum(_ v1: Int32,_ v2: Int32) -> Int32

@_silgen_name 函數(shù)必須是存在的

OC調(diào)用Swift

- 默認(rèn)生成一個(gè)橋接頭文件 文件名格式默認(rèn)為 {targetName}-Swift.h
文件存放的位置.png

Swift里面的類要想暴露給OC 必須繼承于NSObject 要用@objc 修飾需要暴露給OC的成員和方法
可以使用@objcMembers 修飾Swift里面的類 使得整個(gè)類所有內(nèi)容暴露給OC
Xcode會根據(jù)Swift代碼默認(rèn)生成相對應(yīng)的OC代碼 放在{targetName}-Swift.h中
可以使用@objc () 的方法重命名暴露給OC的類名 屬性名 函數(shù)名等

Selector 選擇器

使用#selector(name )定義一個(gè)選擇器 

必須是被@objc 或者 @objcMembers 修飾的方法才可以定義選擇器
因?yàn)檫x擇器依賴于Runtime 而Runtime只在OC中有 Swift里面沒有 所以 必須暴露給OC 才可以選擇器

方法調(diào)用.png

為什么swift 中的暴露給OC的類最終要繼承自NSObject

 OC依賴于Runtime Runtime要求有isa指針 isa指針一定要繼承自NSObject
 OC的初始化alloc 也要繼承自NSObject

Swift調(diào)用OC中的內(nèi)容 底層是怎么調(diào)用的 返回來 OC調(diào)用Swift底層又是如果調(diào)用的

純Swift 調(diào)用方法是虛表 也就是一個(gè)call一個(gè)假地址 然后尋找到真正的地址去調(diào)用方法
- Swift調(diào)用OC中方法是走的msg_send方法
- OC調(diào)用Swift方法是runtime流程  msg_send

如果swift類繼承自NSObject 使用@objcMembers修飾 那么在swift里面調(diào)用swift方法走的是swift的方式 不走OC的msg_send流程
當(dāng)你想走OC的msg_send流程 的時(shí)候 那么在方法前加dynamic進(jìn)行修飾

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,666評論 1 32
  • 基本語法: 定義變量和常量: let 和 var常量和變量的命名:你可以使用任何你喜歡的字符作為常量和變量名,包括...
    西風(fēng)頌閱讀 1,593評論 1 9
  • Swift2.0 1.defer譯為延緩、推遲之意類似棧 注意作用域,其次是調(diào)用順序——即一個(gè)作用域結(jié)束(注意),...
    zeqinjie閱讀 3,512評論 0 50
  • iOS開發(fā)中,我們需要根據(jù)用戶需要去適配各種各樣的版本,特別是蘋果爸爸的每一次新版本發(fā)布,作為開發(fā)者的我們永遠(yuǎn)是最...
    青蘋果園閱讀 7,673評論 2 12
  • 第二篇. 查找、替換、定位 1.小數(shù)變整數(shù) 選取數(shù)字區(qū)域,ctrl+h打開替換窗口,查找.*,替換留空然后點(diǎn)全部替...
    溫暖在靠近閱讀 1,125評論 0 1

友情鏈接更多精彩內(nèi)容