美文网首页
23-从OC到swift

23-从OC到swift

作者: bytebytebyte | 来源:发表于2020-10-31 11:22 被阅读0次
//从OC到swift1-27 在TestSwift2中查看
//7.String
//swift的字符串类型,跟OC的NSString,在API设计上还是有较大差异
//空字符串
var emptyStr1 = ""
var emptyStr2 = String()
var str: String = "1"
str.append("_2") //拼接
str = str + "_3" //重载
str += "_4"    //重载
str = "\(str)_5" //插值
print(str.count) //1_2_3_4_5
var str0 = "123456"
print(str0.hasPrefix("123")) //true
print(str0.hasSuffix("456")) //true

//8.String的插入和删除
var str1 = "1_2"
str1.insert("_", at: str1.endIndex) //1_2_
str1.insert(contentsOf: "3_4", at: str1.endIndex)//1_2_3_4
str1.insert(contentsOf: "666", at: str1.index(after: str1.startIndex)) //1666_2_3_4
str1.insert(contentsOf: "888", at: str1.index(before: str1.endIndex)) //1666_2_3_8884"
str1.insert(contentsOf: "hello", at: str1.index(str1.startIndex, offsetBy: 4)) //1666hello_2_3_8884"
str1.remove(at: str1.firstIndex(of: "1")!) //666hello_2_3_8884
str1.removeAll { $0 == "6" } //hello_2_3_8884
var range = str1.index(str1.endIndex, offsetBy: -4)..<str1.index(before: str1.endIndex)
str1.removeSubrange(range) //hello_2_3_4

//9.Substring
//String可以通过下标、prefix、suffix等截取子串,子串类型不是String、而是Substring.
//Substring和它的base,共享字符串数据
var str2 = "1_2_3_4_5"
var subStr1 = str2.prefix(3) //1_2
var subStr2 = str2.suffix(3) //4_5
var range1 = str2.startIndex..<str2.index(str2.startIndex, offsetBy: 3)
var subStr3 = str2[range1] //1_2
print(subStr3.base) //最初的String 1_2_3_4_5
var str3 = String(subStr3) //Substring -> String 1_2 //Substring转为String时,会分配新的内存字符串数据

subStr3.append(contentsOf: "666") //1_2666 ////Substring发生修改时,会分配新的内存字符串数据
print(str2,subStr3) // 1_2_3_4_5  1_2666

//10.String与Character
for c in "jack" { //c是Character类型
    print(c) //j //a //c // k
}
var str4 = "jack"
var c = str4[str4.startIndex] //c是Character类型 //j

//11.String相关的协议
/*
 String、Array都遵守了这2个协议
 BidirectionalCollection协议包含的部分内容:startIndex、endIndex属性、index方法
 RangeReplaceableCollection协议包含的部分内容:append、insert、remove方法
 Dictionary、Set也有实现上述协议中声明的一些方法,只是并没有遵守上述协议
 */

//12.多行String,如果要显示3引号,至少转义1个引号, 缩进以结尾的3引号为对齐线
let str5 = """
            1 ""\"
                "2"
        3
      '4'
      """
print(str5)

//13.String与NSString
//String与NSString之间可以随时随地桥接转换
//如果你觉得String的API过于复杂难用,可以考虑将String转为NSString
import Foundation
func test0() {
    var str1: String = "jack"
    var str2: NSString = "rose"
    var str3 = str1 as NSString //修改str1不影响str3 它们肯定是2个不同的东西
    var str4 = str2 as String //修改str2不影响str4
    var str5 = str3.substring(with: NSRange(location: 0, length: 2))
    print(str5)
    //比较字符串是否相等
    //String使用==运算符
    //NSString使用isEqual方法,也可用==运算符,本质还是调用了isEqual方法,看汇编看出来的
}
test0()

//14.swift、OC桥接转换表 是通过as的意思
/* //swift不能转OC的可变,其他的都可以
 String <=> NSString
 String <-  NSMutableString
 Array  <=> NSArray
 Array  <-  NSMutableArray
 Dictionary <=> Dictionary
 Dictionary <-  NSMutableDictionary
 Set   <=> NSSet
 Set   <-  NSMutableSet
 */
func test1() {
    var str = "123456"
//    var str2 = str as NSMutableString
    var str2 = NSMutableString(string: str) //真要转也可以
}
test1()

//*** class Person和class Person: NSObject内存结构
import Foundation
class Person: NSObject {
    var age = 10
    var weight = 20
}
var p = Person()
//print(Mems.memStr(ofRef: p))
//不加继承32字节 0x000000010000c338 0x0000000200000002 0x000000000000000a 0x0000000000000014 //meta data、引用计数、age、weight
//加继承32字节 0x011d80010000c331 0x000000000000000a 0x0000000000000014 0x0000000000000000
//isa、age、weight、对齐的

//15.只能被Class继承的协议,就不能被结构体等继承了
protocol Runnable1: AnyObject {} //AnyObject
protocol Runnable2: class {} //class
@objc protocol Runnable3 {} //@objc

//16.可选协议
//第1种方式,通过extension实现
protocol Runnable {
    func run1()
    func run2()
}
extension Runnable {
    func run1() {}
}
//第2种方式:可以通过@objc定义可选协议,这种协议只能被class遵守
@objc protocol Walknabble {
    func walk1()
    @objc optional func wakl2()
    func walk3()
}
class Dog: Walknabble {
    func walk1() {
        print("Dog walk1")
    }
    func walk3() {
        print("Dog walk3")
    }
}
var d = Dog()
d.walk1() //Dog walk1
d.walk3() //Dog walk3

//17.dynamic
//被@objc dynamic修饰的内容会具有动态性,比如调用方法会走Runtime那一套
class Stone: NSObject {
    @objc dynamic func test1() {}
    func test2() {}
}
var t = Stone()
t.test1() //看汇编 走 objc_msgSend
t.test2() //走虚函数

//18.KVC\KVO
//swift支持KVC\KVO的条件,属性所在类、监听器最终继承自NSObject,用@objc dynamic修饰对应的属性
class Observer: NSObject {
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        print("observeValue", change?[.newKey] as Any)
    }
}
class Time: NSObject {
    @objc dynamic var age: Int = 0
    var observer: Observer = Observer()
    override init() {
        super.init()
        self.addObserver(observer, forKeyPath: "age", options: .new, context: nil)
        
    }
    deinit {
        self.removeObserver(observer, forKeyPath: "age")
    }
}
var tt = Time()
tt.age = 20 //serveValue Optional(20)
tt.setValue(25, forKey: "age") //observeValue Optional(25)

//19.blcok方式的KVO
class Phone: NSObject {
    @objc dynamic var age: Int = 0
    var observation: NSKeyValueObservation?
    override init() {
        super.init()
        observation = observe(\Phone.age, options: .new, changeHandler: { (phone, change) in
            print(change.newValue as Any)
        })
    }
}
var pp = Phone()
pp.age = 20 //Optional(20)
pp.setValue(25, forKey: "age") //Optional(25)

//20.关联对象
//在swift中,class依然可以使用关联对象,默认情况下,extension不可以增加存储属性,借助关联对象,可以实现类似extension为class增加存储属性的效果
class Egg{}
extension Egg {
    private static var AGE_KEY: Void? // Void?类型只占一个字节
    private static var WEIGHT_KEY = false //Bool类型只占一个字节
    var age: Int {
        get {
            objc_getAssociatedObject(self, &Self.AGE_KEY) as? Int ?? 0
        }
        set {
            objc_setAssociatedObject(self, &Self.AGE_KEY, newValue, .OBJC_ASSOCIATION_ASSIGN)
        }
    }
    var weight: Int {
        get {
            objc_getAssociatedObject(self, &Self.WEIGHT_KEY) as! Int
        }
        set {
            objc_setAssociatedObject(self, &Self.WEIGHT_KEY, newValue, .OBJC_ASSOCIATION_ASSIGN)
        }
    }
}
var egg = Egg()
egg.age = 10 //10
egg.weight = 20 //20

//21.资源名管理
//这种做法实际是参考了Android的资源名管理方式
import UIKit
enum R {
    enum string: String {
        case add = "添加"
    }
    enum image: String {
        case logo
    }
    enum segue: String {
        case login_main
    }
}

//let img = UIImage(named: "logo")
//let btn = UIButton(type: .custom)
//btn.setTitle("添加", for: .normal)

let img = UIImage(named: R.image.logo.rawValue)
let btn = UIButton(type: .custom)
btn.setTitle(R.string.add.rawValue, for: .normal)

//22.资源名管理的其他思路
let img0 = UIImage(named:"logo")
let font0 = UIFont(name: "Arial", size: 14)

enum T {
    enum image {
        static var logo = UIImage(named: "logo")
    }
    enum font {
        static func arial(_ size: CGFloat) -> UIFont? {
            UIFont(name: "Arial", size: size)
        }
    }
}
let img1 = T.image.logo
let font1 = T.font.arial(14)

//23.多线程开发-异步
//小技巧:swift中NSThread打不出来时用打Thread
print(Thread.current,"main")
DispatchQueue.global().async {
    DispatchQueue.main.async {
        
    }
}
//或者
let item = DispatchWorkItem {
    print("1", Thread.current)
}
DispatchQueue.global().async(execute: item)
item.notify(queue: DispatchQueue.main) {
    
}
//或者封装上面的一下 TestSwift2查看多线程即
public typealias Task = () -> Void
public struct Asyncs {
    public static func async(_ task: @escaping Task) {
        _async(task)
    }
    public static func async(_ task: @escaping Task, _ mainTask: @escaping Task) {
        _async(task, mainTask)
    }
    private static func _async(_ task: @escaping Task, _ mainTask: Task? = nil) {
        let item = DispatchWorkItem(block: task)
        DispatchQueue.global().async(execute: item)
        if let main = mainTask {
            item.notify(queue: DispatchQueue.main, execute: main)
        }
    }
}
Asyncs.async {
    print(1) //1
}
Asyncs.async {
    print("1111", Thread.current)
} _: {
    print("2222", Thread.current)
}
//1111 <NSThread: 0x600001cf4340>{number = 7, name = (null)}
//2222 <NSThread: 0x600001cb4080>{number = 1, name = main}

//24.多线程开发-延迟
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) {
    print("1")
}

//25.多线程开发-异步延迟  TestSwift2查看多线程开发-异步延迟

//26.多线程开发-once TestSwift2查看

//27.多线程开发-加锁 TestSwift2查看
//DispatchSemaphore
public struct Cache0 {
    private static var data = [String: Any]()
    private static var lock = DispatchSemaphore(value: 1) //同时只有一个线程访问
    public static func get(_ key: String) -> Any? {
        data[key]
    }
    public static func set(_ key: String, _ value: Any) {
        lock.wait() //锁
        defer {
            lock.signal() //解锁
        }
        data[key] = value
    }
}

//NSLock
public struct Cache1 {
    private static var data = [String: Any]()
    private static var lock = NSLock()
    public static func get(_ key: String) -> Any? {
        data[key]
    }
    public static func set(_ key: String, _ value: Any) {
        lock.lock() //锁
        defer {
            lock.unlock() //解锁
        }
        data[key] = value
    }
}

//NSRecursiveLock
public struct Cache2 {
    private static var data = [String: Any]()
    private static var lock = NSRecursiveLock()
    public static func get(_ key: String) -> Any? {
        data[key]
    }
    public static func set(_ key: String, _ value: Any) {
        lock.lock() //锁
        defer {
            lock.unlock() //解锁
        }
        data[key] = value
    }
}

相关文章

  • 23-从OC到swift

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

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

  • 从OC到Swift

    Swift调用OC类和方法 在工程名-Bridging-Header.h中添加需要调用OC类的头文件.h OC调用...

  • 从OC到Swift

    MARK、TODO、FIXME 条件编译 打印 系统版本检测 API可用性说明 更多用法 iOS程序的入口 在Ap...

  • 从OC到Swift(二)

    swift系列课程 协议

  • 从OC到Swift(一)

    swift系列课程 @select 是oc Runtime那一套东西,swift本身没有runtime的 1.为什...

  • 二十、从OC到Swift

    1、MARK 、TODO、FIXME MARK: 类似OC中的#pragma mark MARK: - 类似OC中...

  • 从OC到Swift(一)

    开篇 在简单的学习了swift语法之后,开始在项目里使用。很多东西都是别人铺好路,自己只是套用写UI而已。这里先简...

  • 从OC到Swift (二)

    协议 只能被class继承的协议 被@objc修饰的协议,还可以暴露给OC去遵守实现 可以通过@objc定义可选协...

  • 从OC到Swift (一)

    oc的入口:main.m文件中 swift的入口:AppDelegate.swift文件中顶部@main标记,表示...

网友评论

      本文标题:23-从OC到swift

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