- UnsafePointer
- C 指针内存管理
- COpaquePointer 和 C convention
- GCD 和延时调⽤
- 获取对象类型
- 自省
—
UnsafePointer – 专门针对指针的转换
swift 思想中,所有的引用或者变量的类型都是确定并且正确对应他们的实际类型的。不能进行任意的类型转换或者通过指针做出一些出格的事。
UnsafePointer
和它的一系列变体,是一套对C语言指针的访问和转换方法。对于 C语言中接受内存地址作为参数,Swift中会将它转为 UnsafePointer<type>
类型。
C语言 | Swift语言 |
---|---|
const Type * | UnsafePointer |
Type * | UnsafeMutablePointer |
C中,取地址中的值使用*
, Swift 则可以用 memory
取值
方法传参是指针地址的时候,Swift和C都是一样的在变量名前加上&
使用unsafeBitCast
强制转换
// unsafeBitCast 会将第一个参数的内容按照第二个参数的类型进行转换,而不必担心是否可行。这也是 `unsafe` 所在。
let str = unsafeBitCast(CFArrayGetValueAtIndex(arr, 0), to: CFString.self)
—
C 指针内存管理
swift无法对C指针进行自动内存管理。需要手动进行内存管理,管理原则是 谁申请、谁释放。
创建一个指针使用 allocate
和initialize
,最后使用deinitialize
和deallocate
释放指针指向的内存的对象以及指针自身本身。
指针的内存申请也可以用malloc
或者calloc
,这时候释放使用free
—
COpaquePointer 和 C convention
C中有一种指针,在头文件中找不到定义,实现细节也被隐藏起来。称为不透明指针(Opaque Pointer)。
swift中对应这中不透明指针的类型是COpaquePointer
C中能确定类型的指针,swfit中使用UnsafePointer
对应。
C中的函数指针,在swift中可以转换为闭包,不过需要加上@convention
标注
—
GCD 和延时调⽤
可以使用GCD里的asyncAfter
实现延时的功能。
let interval : TimeInterval = 2.0
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + interval) {
print("刷新UI")
}
—
获取对象类型
// 使用 type(of:)
let new = "hhhhhhh"
let type0 = type(of: new)
let p = People()
let type1 = type(of: p)
print("type0 is \(type0), type1 is \(type1)" )
—
自省
向一个对象发出询问,以确定它是否是某个类型,叫做自省。
//OC:
[obj1 isKindOfClass:[ClassA class]];
[obj2 isMemberOfClass:[ClassB class]];
//Swift中,NSObject的子类同样可是使用上面两个方法.
let u = User.sharedUser
let b0 = u.isKind(of: User.self) //true
let b1 = u.isMember(of: People.self) //false
//不是继承自NSObject的类型
class People { }
let p1 : AnyObject = People()
let b2 = p1.isKind(of: People.self) //true
let b3 = p1.isKind(of: User.self) //false
//不是继承自NSObject的类,还可以用 `is` 判断类型
let p2 : AnyObject = People()
if (p2 is User) {
print("p2 是 User")
} else if (p2 is People) {
print("p2 是 People") //输出这一行
}
//如果编译器能够确定实例的类型,使用`is`会有警告提示。
let p3 = People()
if (p3 is People) { //⚠️提示: "is" test always true
print("p3 是 people")
}