AnyObject:代表任意类的实例,类的类型,仅类遵守的协议
AnyClass 代表任意实例的类型
Any 代表任意的类型
T.self: T是实例对象,当前T.self返回的就是他本身;如果 T 是类,当前 T.self 返回的就是元类型
let t = LGTeacher()
let t1: AnyObject = t.self
let t2: AnyObject = LGTeacher.self
let t3: AnyClass = LGTeacher.self
t2是MetaData地址,
LGTeacher.self 是AnyClass或AnyObject
Self 类型不是特定类型,⽽是让您⽅便地引⽤当前类型,⽽⽆需重复或知道该类型的名称。
在协议声明或协议成员声明中,Self 类型是指最终符合协议的类型。
作为⽅法的返回类型, 作为只读下标的返回类型,作为只读计算属性的类型
protocol MyProtocol {
func get() -> Self
}
type(of: value) 动态类型分析
let age = 10
func test(_ value: Any) {
print(type(of: value))
}
test(age)
test函数调用之前, value 的类型是Any
test函数调用之后, value 的类型是Int
swift调用c函数
1.第一种方式
TestC.c
int lg_add(int a, int b){
return a + b;
}
xxx.swift
@_silgen_name("lg_add")
func swift_lg_add(a: Int32, b: Int32) -> Int32
print(swift_lg_add(a: 10, b: 20))
2.第二种方式,桥接文件
swift Runtime
class LGTeacher{
var age: Int = 18
func teach(){
print("teach")
}
}
let t = LGTeacher()
func test(){
var methodCount:UInt32 = 0
let methodlist = class_copyMethodList(LGTeacher.self, &methodCount)
for i in 0..<numericCast(methodCount) {
if let method = methodlist?[i]{
let methodName = method_getName(method);
print("⽅法列表:\(String(describing: methodName))")
}else{
print("not found method");
}
}
var count:UInt32 = 0
let proList = class_copyPropertyList(LGTeacher.self, &count)
for i in 0..<numericCast(count) {
if let property = proList?[i]{
let propertyName = property_getName(property);
print("属性成员属性:\(String(utf8String: propertyName)!)")
}else{
print("没有找到你要的属性");
}
}
}
1.对于纯 Swift 类来说,⽅法和属性不加任何修饰符的情况下。这个时候其实已经不具备我们所谓的 Runtime 特性了,这和我们在上⼀节课的⽅法调度(V-Table调度)是不谋⽽合的。
2.对于纯 Swift 类,⽅法和属性添加 @objc 标识的情况下,当前我们可以通过 Runtime API 拿到, 但是在我们的 OC 中是没法进⾏调度的。
3.对于继承⾃ NSObject 类来说,如果我们想要动态的获取当前的属性和⽅法,必须在其声明前添加 @objc 关键字,否则也是没有办法通过 Runtime API 获取的。
4.纯swift类没有动态性,但在⽅法、属性前添加dynamic修饰,可获得动态性。
5.继承⾃NSObject的swift类,其继承⾃⽗类的⽅法具有动态性,其它⾃定义⽅法、属性想要获得动 态性,需要添加dynamic修饰。
6.若⽅法的参数、属性类型为swift特有、⽆法映射到objective-c的类型(如Character、Tuple),则 此⽅法、属性⽆法添加dynamic修饰(编译器报错)
Mirror
反射就是可以动态获取类型、成员信息,在运⾏时可以调⽤⽅法、属性等⾏为的特性
获取成员信息
let t = LGTeacher()
let mirror = Mirror(reflecting: t)
print(type(of: mirror.children))
print(mirror.children.count)
for pro in mirror.children {
if let key = pro.label {
print("key: \(key), value: \(pro.value)")
}
}
封装
struct LGJsonMap {
static func jsonMap(_ value: Any) -> Any {
let mirror = Mirror(reflecting: value)
guard !mirror.children.isEmpty else {
return value
}
var result: [String: Any] = [:]
for pro in mirror.children {
if let key = pro.label {
result[key] =jsonMap(pro.value)
}
}
return result
}
}
print(LGJsonMap.jsonMap(t))
lldb打印
class LGTeacher: CustomReflectable {
var age = 18
var student: Student = Student(teacher: "Tom")
static let name = "Jack"
lazy var name1 = Self.name
func test() {
print("test")
}
var customMirror: Mirror{
let info = KeyValuePairs<String, Any>.init(dictionaryLiteral: ("age", age),("student", student.teacher))
let mirror = Mirror.init(self, children: info, displayStyle: .class, ancestorRepresentation: .generated)
return mirror
}
}
Demo
1. unsafeBitCast 可以指针之间转换
2.swift_getTypeByMangledNameInContext swift标准库c函数
3.协议读取Any类型,通过关键字Self,读取真实类型的值
4.读取指针+偏移量的值
UnsafeMutablePointer(mutating: UnsafeRawPointer(p).advanced(by: numericCast(offset)).assumingMemoryBound(to: Pointee.self))
func demo() {
let t = LGTeacher_2()
// let ptr = Unmanaged.passUnretained(t as AnyObject).toOpaque()
// let ptr1 = ptr.bindMemory(to: HeapObject.self, capacity: 1)
// print(ptr1.pointee.metadata)
//
// let ptr2 = ptr1.pointee.metadata.bindMemory(to: Metadata.self, capacity: 1)
// print(ptr2.pointee)
// print(type(of: ptr1.pointee.metadata))
let ptr = unsafeBitCast(LGTeacher_2.self as Any.Type, to: UnsafeMutablePointer<TargetClassMetadata>.self)
let namePtr = ptr.pointee.typeDescriptor.pointee.name.getmeasureRelativeOffset()
print("current class name: \(String(cString: namePtr))")
let numFileds = ptr.pointee.typeDescriptor.pointee.numFields
print("当前类属性的个数: \(numFileds)")
let superClassType = ptr.pointee.typeDescriptor.pointee.superClassType.getmeasureRelativeOffset()
print("current superClassType: \(String(cString: superClassType))")
let offsets = ptr.pointee.typeDescriptor.pointee.getFieldOffsets(UnsafeRawPointer(ptr).assumingMemoryBound(to: Int.self))
print("======= start fetch filed ======")
for i in 0..<numFileds{
let fieldDespritor = ptr.pointee.typeDescriptor.pointee.fieldDescriptor.getmeasureRelativeOffset().pointee.fields.index(of: Int(i)).pointee.fieldName.getmeasureRelativeOffset()
print("--- filed: \(String(cString: fieldDespritor)) info begin ----")
let fieldOffset = offsets[Int(i)]
//Int ,String
let typeMangleName = ptr.pointee.typeDescriptor.pointee.fieldDescriptor.getmeasureRelativeOffset().pointee.fields.index(of: Int(i)).pointee.mangledTypeName.getmeasureRelativeOffset()
print("typeManglename:\(typeMangleName)")
let genericVector = UnsafeRawPointer(ptr).advanced(by: ptr.pointee.typeDescriptor.pointee.genericArgumentOffset * MemoryLayout<UnsafeRawPointer>.size).assumingMemoryBound(to: Any.Type.self)
//HandJSON
let fieldType = swift_getTypeByMangledNameInContext(
typeMangleName,
256,
UnsafeRawPointer(ptr.pointee.typeDescriptor),
UnsafeRawPointer(genericVector)?.assumingMemoryBound(to: Optional<UnsafeRawPointer>.self))
print(fieldType as Any)
//比较难理解,HandJSON
let type = unsafeBitCast(fieldType, to: Any.Type.self)
print(type)
let instanceAddress = Unmanaged.passUnretained(t as AnyObject).toOpaque()
let value = customCast(type: type)
print("fieldType:\(type) \nfieldValue: \(value.get(from: instanceAddress.advanced(by: fieldOffset))) ")
print("--- filed: \(String(cString: fieldDespritor)) info end ---- \n")
}
print("end")
}
CAPI.h
#ifndef CAPI_h
#define CAPI_h
const void * _Nullable swift_getTypeByMangledNameInContext(
const char * _Nullable typeNameStart,
int typeNameLength,
const void * _Nullable context,
const void * _Nullable const * _Nullable genericArgs);
const void * _Nullable swift_allocObject(
const void * _Nullable type,
int requiredSize,
int requiredAlignmentMask);
#endif /* CAPI_h */
协议读取Any类型,通过关键字Self,读取真实类型的值protocol BrigeProtocol {}
extension BrigeProtocol {
static func get(from pointer: UnsafeRawPointer) -> Any {
pointer.assumingMemoryBound(to: Self.self).pointee
}
}
//协议的Metadata:
//协议见证表
struct BrigeProtocolMetadata {
let type: Any.Type
let witness: Int
}
func customCast(type: Any.Type) -> BrigeProtocol.Type {
var container = BrigeProtocolMetadata(type: type, witness: 0)
var protocolType = BrigeProtocol.Type.self
var cast = unsafeBitCast(container, to: BrigeProtocol.Type.self)
return cast
}
struct TargetRelativeDirectPointer<Pointee>{
var offset: Int32
mutating func getmeasureRelativeOffset() -> UnsafeMutablePointer<Pointee>{
let offset = self.offset
return withUnsafePointer(to: &self) { p in
return UnsafeMutablePointer(mutating: UnsafeRawPointer(p).advanced(by: numericCast(offset)).assumingMemoryBound(to: Pointee.self))
}
}
}
struct TargetClassDescriptor{
var flags: Int32
var parent: Int32
var name: TargetRelativeDirectPointer<CChar>
var accessFunctionPointer: TargetRelativeDirectPointer<UnsafeRawPointer>
var fieldDescriptor: TargetRelativeDirectPointer<FieldDescriptor>
var superClassType: TargetRelativeDirectPointer<CChar>
var metadataNegativeSizeInWords: Int32
var metadataPositiveSizeInWords: Int32
var numImmediateMembers: Int32
var numFields: Int32
var fieldOffsetVectorOffset: Int32
func getFieldOffsets(_ metadata: UnsafeRawPointer) -> UnsafePointer<Int>{
return metadata.assumingMemoryBound(to: Int.self).advanced(by: numericCast(self.fieldOffsetVectorOffset))
}
var genericArgumentOffset: Int {
return 2
}
}