美文网首页
Swift十八(OC 到 Swift1)

Swift十八(OC 到 Swift1)

作者: 看谷秀 | 来源:发表于2022-07-20 17:30 被阅读0次

目录

  1. 标记
  2. 条件编译
  3. 系统版本检测 #available
  4. API可用性说明 (过期重写api)
  5. IOS程序入口
  6. Swift调用OC
  7. Swift调用OC – @_silgen_name 重命名
  8. OC调用Swift
  9. OC调用Swift--- @objc() 重新命名
  10. 选择器(Selector)
  11. String 切割 区间 insert append remove
  12. SubString 切割区间
  13. String 与 NSString关系 及 as 转换
一: 标记
// MARK:  类似于OC中的 #pragma mark
// MARK: -  类似于OC中的 #pragma mark -
// TODO:  用于标记未完成的任务
// FIXME:  用于标记待修复的问题
#warning("警告~~~")

func test() -> Int {
    #warning("还没没想好怎么写~~")
    fatalError()
}
二: 条件编译
// 操作系统:macOS\iOS\tvOS\watchOS\Linux\Android\Windows\FreeBSD
#if os(macOS) || os(iOS)
// CPU架构:i386\x86_64\arm\arm64
#elseif arch(x86_64) || arch(arm64)
// swift版本
#elseif swift(<5) && swift(>=3)
// 模拟器
#elseif targetEnvironment(simulator)
// 可以导入某模块
#elseif canImport(Foundation)
#else
#endif

设置debug表示符
1 Active Compilation Conditions 设置
2 Other Swift Flags设置 格式 -D ForTest // ForTest为标识

  override func viewDidLoad() {
        super.viewDidLoad()
        #if DEBUGA
        print("debug!!!!") 
        #else
        print("release!!!!")
        #endif
        // debug模式 打印 debug!!!!
    }
 override func viewDidLoad() {
        super.viewDidLoad()
        #if ForTest
        print("ForTest!!!!")
        #else
        print("release!!!!")
        #endif
        // debug模式 打印 ForTest!!!!
    }
三: 系统版本检测 (available 可获得的)
if #available(iOS 10, macOS 10.12, *) {
// 对于iOS平台,只在iOS10及以上版本执行
// 对于macOS平台,只在macOS 10.12及以上版本执行
// 最后的*表示在其他所有平台都执行
}
四: API可用性说明
@available(iOS 10, macOS 10.15, *)
class Person {}
// 代表ios10以后新增的类

struct Student {
  @available(*, unavailable, renamed: "study")
  func study_() {}
  func study() {}
  // 代表修改了study_函数名为study
  @available(iOS, deprecated: 11)
  @available(macOS, deprecated: 10.12)
  func run() {}
// 代表 ios11或是macos10.12已经过期
}

更多用法参考:https://docs.swift.org/swift-book/ReferenceManual/Attributes.html

五: IOS程序入口

在AppDelegate上面默认有个@main/ @UIApplicationMain 标记,这表示
编译器自动生成入口代码(main函数代码),自动设置AppDelegate为APP的代理
也可以删掉@main/ @UIApplicationMain,自定义入口代码:新建一个main.swift文件


六: Swift调用OC

新建1个桥接头文件,文件名格式默认为:{targetName}-Bridging-Header.h
在 {targetName}-Bridging-Header.h 文件中, #import OC需要暴露给Swift的内容

七: Swift调用OC – @_silgen_name

如果C语言暴露给Swift的函数名跟Swift中的其他函数名冲突了
可以在Swift中使用 @_silgen_name 修改C函数名
注意: 是oc暴露的c函数

八: OC调用Swift

1 Xcode已经默认生成一个用于OC调用Swift的头文件,文件名格式是: {targetName}-Swift.h
// 搜不到, 可以先#import 下看是否报错

2 @objc @ objcMembers

Swift 通过添加@objcMembers 把swift文件暴露给OC调用, 提现在{targetName}-Swift.h文件中, 包括其扩展extension中的方法也会暴露给OC调用

九: OC调用Swift--- @objc() 重新命名

可以通过 @objc 重命名Swift, 暴露给OC的符号名(类名、属性名、函数)

十: 选择器(Selector)

Swift中依然可以使用选择器,使用#selector(name)定义一个选择器
必须是被@objcMembers或@objc修饰的方法才可以定义选择器

@objcMembers class Person: NSObject {
  func test1(v1: Int) { print("test1") }
  func test2(v1: Int, v2: Int) { print("test2(v1:v2:)") }
  func test2(_ v1: Double, _ v2: Double) { print("test2(_:_:)") }

  func run() {
    perform(#selector(test1))
    perform(#selector(test1(v1:)))
    perform(#selector(test2(v1:v2:)))
    perform(#selector(test2(_:_:)))
    perform(#selector(test2 as (Double, Double) -> Void))
  } 
}

dynamic 修饰swift方法, 会执行oc的消息机制. (否则执行原来的虚标调用)

十一: String

1 String 基本操作

var emptyStr1 = ""
var empty = String()
var str: String = "1"
// 拼接2
str.append("_2") // "1_2"
// 重载运算符 +
str = str + "_3" // 1_2_3
// 重载运算符 +=
str += "_4" // 1_2_3_4
// \()插值
str = "\(str)_5"  // 1_2_3_4_5
print(str.count) // 长度,9,1_2_3_4_5
var str = "123456"
print(str.hasPrefix("123")) // true
print(str.hasSuffix("456")) // true

2 String 插入删除操作 & 补充 insert & remove & append

var str = "1_2"
//  str.endIndex 是末尾元素后         
str.insert("_", at: str.endIndex) // 1_2_
        
str.insert(contentsOf: "3_4", at: str.endIndex) // 1_2_3_4
//  str.startIndex 是第一个元素前   
str.insert(contentsOf: "0_", at: str.startIndex) //0_1_2_3_4
        
str.insert(contentsOf: "666", at: str.index(after: str.startIndex)) // 0666_1_2_3_4
        
str.insert(contentsOf: "888", at: str.index(before: str.endIndex)) // 0666_1_2_3_8884
        
str.insert(contentsOf: "hello", at: str.index(str.startIndex, offsetBy: 4)) // 0666hello_1_2_3_8884
// 删除第一次出现的字符
str.remove(at: str.firstIndex(of: "8")!) // 0666hello_1_2_3_884
// 删除所有为 6 的字符        
str.removeAll { $0 == "6" }  // "0hello_1_2_3_884"
// 区间截取
let range: Range<String.Index> = str.index(str.endIndex, offsetBy: -4)..<str.index(before: str.endIndex)
str.removeSubrange(range) // 0hello_1_2_34
// 拼接字符串
str.append("_append") // 0hello_1_2_34_append
var newStr = "88888666"
newStr.removeAll { (char) -> Bool in
     return char == "8"
}
print(newStr)
// str.removeAll(where: (Character) throws -> Bool)  // 入参传个闭包
// removeAll函数会遍历字符串, 返回每个字符给char变量

// 根据Range 切割数组     
var rangeArray = ["1", "2", "3", "4"]
let needRange = 1...2
rangeArray.removeSubrange(needRange)
print(rangeArray)
// swift 的Range是区间运算符
十二: SubString

1 SubString & String 关系
String 和 SubString 都是结构体没有继承关系

substring 指针指向了原String, 引用关系, 并没有发生拷贝
subString转为String, 才发生了拷贝

2 通过subString操作字符串截取操作

// String可以通过下标、 prefix、 suffix等截取子串,子串类型不是String,而是Substring
var str = "1_2_3_4_5"
// 1_2
var substr1 = str.prefix(3) // subString类型
// 4_5
var substr2 = str.suffix(3) // subString类型
// 1_2
var range = str.startIndex ..< str.index(str.startIndex, offsetBy: 3)
var substr3 = str[range] // subString类型
// 最初的String,1_2_3_4_5
print(substr3.base) // 获取原来的String
// Substring -> String
var str2 = String(substr3) // // String类型
// 切割字符串
let strr = "12345678"
let subrange = strr.index(after: strr.startIndex) ..< strr.index(before: strr.endIndex)
let subStr = strr[subrange]
print(subStr) // 234567
     
let str2 = "12345678"
let subrange2 = str2.startIndex ... str2.index(str2.startIndex, offsetBy: 4)
let subStr2 = str2[subrange2]
print(subStr2) //12345

Substring和它的base,共享字符串数据
Substring发生修改 或者 转为String时,会分配新的内存存储字符串数据

3 String 与 Character

for c in "jack" { // c是Character类型
    print(c)
}

var str = "jack" // c是Character类型
var c = str[str.startIndex] // c是Character类型 j
十三: String 与 NSString关系 及 as 转换

1 String 与 NSString 之间可以随时随地桥接转换
2 如果你觉得String的API过于复杂难用,可以考虑将String 转为NSString

// String 转 NSString   方便操作字符串切割
let str = "123456789"
let str1 = str as NSString  // 转oc字符串
let str3 = str1.substring(with: NSRange(location: 3, length: 2)) // 45

// NSString 转 String
let str5 : NSString = "0987654321"
var str6 = str5 as String
str6.append("-111") // 0987654321-111
        
// 对比  NSString VS String  截取字符串
// ~OC截取
let str2 = str1.substring(from: 4) // 56789    
// ~Swift截取
let str4 = str[str.index(str.startIndex, offsetBy: 4) ... str.index(before: str.endIndex)] // 56789 

桥接转换表
String 和 NSString 相互转换, 本质是通过桥接进行的
双向箭头: 代表可以互相转换

// Mutable类型不能通过桥接转换, 可以通过方法直接创建
let str7 = NSMutableAttributedString(string: "test")

相关文章

  • Swift十八(OC 到 Swift1)

    目录 标记 条件编译 系统版本检测 #available API可用性说明 (过期重写api) IOS程序入口 S...

  • 面试题

    Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...

  • 从 OC 到 Swift 的快速入门与专业实践

    从 OC 到 Swift 的快速入门与专业实践 从 OC 到 Swift 的快速入门与专业实践

  • OC & Swift 嵌套工程

    OC工程使用Swift 工程配置 首先准备好目标OC工程,将需要集成到OC工程中的Swift文件拖入工程。此处我们...

  • Swift与OC混编

    标签:Swift 在Swift中调用OC 首先创建OC/Swift工程 然后创建swift/OC文件,Xcode会...

  • 2018-03-28 初始Swift 001

    随笔1、swift使用OC:新建或者拖拽一个OC文件到swift项目中,swift项目会自动生成桥接文件。把需要是...

  • oc Swift 混编

    oc Swift 混编 oc 项目 混编Swift1.1 oc 调用 Swift 的类 和 方法步骤: ...

  • Podfile中的 use_frameworks!

    use_frameworks! A、用cocoapods 导入swift 框架 到 swift项目和OC项目都必须...

  • Podfile中的 use_frameworks!

    use_frameworks! A、用cocoapods 导入swift 框架 到 swift项目和OC项目都必须...

  • ios oc和swift混合使用,桥接

    swift创建oc自动生成Bridging-Header,放入oc头文件,swift即可使用oc使用swift需要...

网友评论

      本文标题:Swift十八(OC 到 Swift1)

      本文链接:https://www.haomeiwen.com/subject/btyeirtx.html