Swift小结
2019-09-25 本文已影响0人
纳兰沫
//TODO: 用于标记未完成的任务
// FIXNE: 用于标记待修复的问题
//#warning("todo") 警告
条件编译
//操作系统
#if os(macOS) || os(iOS)
//CPU架构
#elseif arch(x86_64) || arch(arm64)
//swift版本
#elseif swift(<5) && swift(>=3)
//模拟器
#elseif targetEnvironment(simulator)
//可以导入某模块
#elseif canImport(Foundation)
#else
#endif
强制断言.png
#if DEBUG
DEBUG 模式
#else
release 模式
#endif
如果需要自己自定义编译器模式 那么可以
第一种方法
在DEBUG 后面加空格再加上自己的编译器模式
第二种方法
在里面填写-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
}
系统版本检测
if #available(iOS 10,macOS 10.12, *){
//对与ios平台 只在ios10以及以上版本执行
//对于macOS平台 只在macOS 10.12及以上版本执行
//最后的* 表示在其他所有平台都执行
}
API可用性
struct Student {
//study_不可用 改名为study
@available(*,unavailable,renamed: "study")
func study_() {
}
func study() {
}
@available(iOS, deprecated: 11)
//macOS 的10.12开始 这个run方法不可用
@available(macOS, deprecated: 10.12)
func run() {
}
}
var stu = Student()
stu.run()
错误.png
ios程序入口
1.在AppDelegate上面默认有个@UIApplicationMain标记 表示
编译器自动生成入口代码(main函数代码) 自动设置AppDelegate为App的代理
2.也可以删除@UIApplicationMain 自定义入口代码 新建一个main.swift文件
import Foundation
import UIKit
class MyApplication: UIApplication {
}
UIApplicationMain(CommandLine.argc,
CommandLine.unsafeArgv,
NSStringFromClass(MyApplication.self),
NSStringFromClass(AppDelegate.self))
Swift调用OC
- 新建一个桥接头文件 文件名格式默认为 {targetName}-Bridging-Header.h
- 在相应的位置写入桥接头文件的位置
写入桥接头文件的位置.png
如果C语言暴露给Swift的函数跟Swift的函数冲突了 可以在swift中使用@_silgen_name 修改C函数名
@_silgen_name("sum")
func swift_sum(_ v1: Int32,_ v2: Int32) -> Int32
@_silgen_name 函数必须是存在的
OC调用Swift
- 默认生成一个桥接头文件 文件名格式默认为 {targetName}-Swift.h
文件存放的位置.png
Swift里面的类要想暴露给OC 必须继承于NSObject 要用@objc 修饰需要暴露给OC的成员和方法
可以使用@objcMembers 修饰Swift里面的类 使得整个类所有内容暴露给OC
Xcode会根据Swift代码默认生成相对应的OC代码 放在{targetName}-Swift.h中
可以使用@objc () 的方法重命名暴露给OC的类名 属性名 函数名等
Selector 选择器
使用#selector(name )定义一个选择器
必须是被@objc 或者 @objcMembers 修饰的方法才可以定义选择器
因为选择器依赖于Runtime 而Runtime只在OC中有 Swift里面没有 所以 必须暴露给OC 才可以选择器
为什么swift 中的暴露给OC的类最终要继承自NSObject
OC依赖于Runtime Runtime要求有isa指针 isa指针一定要继承自NSObject
OC的初始化alloc 也要继承自NSObject
Swift调用OC中的内容 底层是怎么调用的 返回来 OC调用Swift底层又是如果调用的
纯Swift 调用方法是虚表 也就是一个call一个假地址 然后寻找到真正的地址去调用方法
- Swift调用OC中方法是走的msg_send方法
- OC调用Swift方法是runtime流程 msg_send
如果swift类继承自NSObject 使用@objcMembers修饰 那么在swift里面调用swift方法走的是swift的方式 不走OC的msg_send流程
当你想走OC的msg_send流程 的时候 那么在方法前加dynamic进行修饰