//
// CategoryBasementInitializeViewController.swift
// iOS底层
//
// Created by yanqunchao on 2019/5/17.
// Copyright © 2019 yanqunchao. All rights reserved.
//
import UIKit
class CategoryBasementInitializeViewController: UIViewController {
/**
* 方法类
*/
class MethodT: NSObject {
var name:Selector?
var type:String?
var imp:String?
}
/**
* 方法列表类
*/
class MethodListT: NSObject {
var size:Int? //方法列表内存大小
var methodCount:Int? //方法数量
var methodList:[MethodT]? //方法数组
}
/**
* 只读类类信息
*/
class ClassRoT: NSObject {
var name:String = ""
var baseMethodList:[MethodListT]? // 实例方法列表
}
/**
* 可读可写的类信息
*/
class ClassRwT: NSObject {
var ro:ClassRoT?
var methods:[MethodListT]? //方法列表
}
/**
* 方法缓冲区类
*/
class BucketT: NSObject {
var key:Selector? //SEL
var imp:String? //IMP
}
/**
* 方法缓存类
*/
class CacheT: NSObject {
var buckets:[BucketT] = Array.init(repeating: BucketT(), count: 4)
var mask:Int = 3
var occupied:Int?
}
/**
* 类对象
*/
class ClassT: NSObject {
var isa:ClassT? //指针
var superClass:ClassT? //父类
var cache:CacheT? //方法缓存
var rw:ClassRwT? //可读可写类
var name:String?
var isInitialized:Bool = false
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .white
objMessageSend(inst: studentClass, sel: NSSelectorFromString("alloc"))
objMessageSend(inst: personClass, sel: NSSelectorFromString("alloc"))
objMessageSend(inst: personClass, sel: NSSelectorFromString("alloc"))
}
//消息发送
func objMessageSend(inst:ClassT, sel:Selector){
let cls = inst.isa //找到元类,通过元类找到类方法。
// print("\(cls!.name!)------执行了\(sel)")
classLookupMethodAndLoadCache3(inst: inst, sel: sel, cls: cls!)
}
//消息发送机制入口函数(从类中查找方法,并加载缓存)
func classLookupMethodAndLoadCache3(inst:ClassT, sel:Selector, cls:ClassT){
lookUpImpOrForward(cls: cls, inst: inst, sel: sel, initialize: true, cache: false)
}
//方法寻找或转发
func lookUpImpOrForward(cls:ClassT, inst:ClassT, sel:Selector, initialize:Bool, cache:Bool){
//先从自己缓存中找
if cacheLookup(inst: cls, sel: sel) == nil{ //找不到
// print("\(inst.name!)的缓存中没找到\(NSStringFromSelector(sel))")
//去方法列表中找
if methodTableLookup(inst: cls, sel: sel) == nil { //找不到
// 消息动态处理 、消息转发
} else{
// print("调用\(inst.name!)的\(sel)")
}
}else{
// print("调用\(inst.name!)的\(sel)")
}
//该类没有调用过+initialize方法时,调用classInitialize
if (initialize && !isInitialized(cls: cls) ) {
let noMetaCls = getNoMetaClass(clsName: cls.name!)!
classInitialize(cls: noMetaCls) //调的非元类对象
}
}
//从缓存中找
func cacheLookup(inst:ClassT, sel:Selector) ->String?{
let cls = inst
let bucket = find(key: sel, id: cls)
if bucket != nil {
// print("从\(cls.name!)的缓存中找到了\(NSStringFromSelector(sel))方法")
return bucket?.imp
}else{
return nil
}
}
func find(key:Selector,id:ClassT) ->BucketT? {
let buckets = id.cache?.buckets
let m = id.cache?.mask
if m == nil || m == -1{
return nil
}
//获取起始索引
let begin = cacheHash(key: key, mask: m!)
var i = begin
repeat {
let bucket = buckets![i!]
if bucket.key == nil{
}else if bucket.key! == key{
// print("\(id.name!)查找到的索引\(i!)")
return bucket
}
// print("\(id.name!)查找索引\(i!)")
i = cacheNext(i: i!, mask: m!)
}while(i != begin)
return nil
}
//缓存方法
func cache(bkt:BucketT,id:ClassT) {
// print("缓存\(id.name!)的\(NSStringFromSelector(bkt.key!))方法")
var buckets = id.cache?.buckets
let m = 3
let key = bkt.key
//获取起始索引
let begin = cacheHash(key: key!, mask: m)
var i = begin
var bucket = buckets![i!]
repeat {
if bucket.key == nil{
buckets![i!] = bkt
id.cache?.buckets = buckets!
break
}
i = cacheNext(i: i!, mask: m)
bucket = buckets![i!]
}while(i != begin)
}
func cacheNext(i:Int,mask:Int) ->Int? {
var index = i
if index != 0 {
index = index - 1
return index
}else {
return mask
}
}
func cacheHash(key:Selector,mask:Int) ->Int? {
let keyAddr = Unmanaged.passUnretained(key as AnyObject).toOpaque()
let keyAddrStr = "\(keyAddr)"
let lastKeyStr = keyAddrStr.suffix(keyAddrStr.count - 2)
let keyInt = ConvertUtil.hexTodec(number: String(lastKeyStr))
return keyInt & mask
}
//从类的方法列表中找
lazy var lookupedCls:[ClassT] = []
func methodTableLookup(inst:ClassT, sel:Selector) ->String? {
lookupedCls.append(inst)
let methodList = inst.rw?.methods
if methodList != nil && methodList?.count != 0 {
//先遍历自己类的方法
for methodListT in methodList! {
for method in methodListT.methodList! {
if method.name == sel { //找到,直接返回
// print("\(inst.name!)找到了\(NSStringFromSelector(sel))")
let bucket = BucketT()
bucket.key = sel
bucket.imp = "\(NSStringFromSelector(sel))的实现"
let recCls = lookupedCls.first!
cache(bkt: bucket, id: recCls) //找到该方法,缓存到自己的类中。
lookupedCls.removeAll()
return method.imp!
}
}
}
}
// print("\(inst.name!)没找到\(NSStringFromSelector(sel))")
let superClass = inst.superClass
if superClass == nil {
return nil
}else{
return methodTableLookup(inst: superClass!, sel: sel)
}
}
//方法初始化
func classInitialize(cls:ClassT){
//获取父类
let superClass = cls.superClass
if (superClass != nil) && !isInitialized(cls: superClass!) {
classInitialize(cls: superClass!) //递归调用
}
print("\r\n\r\n\r\n----------\(cls.name!)-----------")
callInitialize(cls: cls)
}
//调用初始化方法
func callInitialize(cls:ClassT?) {
// print("--------------------初始化了\(cls!.name!)的方法")
let metaCls = cls?.isa
metaCls?.isInitialized = true
objMessageSend(inst: cls!, sel: NSSelectorFromString("--------initialize"))
}
//该类是否已经初始化
func isInitialized(cls:ClassT) -> Bool{ //判断传入的类是否是元类
if (cls.name?.contains("Meta"))! {//是,直接返回
return cls.isInitialized
}else{ //不是,获取其元类
return cls.isa!.isInitialized
}
}
// lazy var goodStudentClass:ClassT = {
// let cls = ClassT()
// cls.name = "MJGoodStudent"
// cls.isa = goodStudentMetaClass
// cls.superClass = studentClass
// return cls
// }()
lazy var studentClass:ClassT = {
let cls = ClassT()
cls.name = "MJStudent"
cls.isa = studentMetaClass
cls.superClass = personClass
return cls
}()
lazy var personClass:ClassT = {
let cls = ClassT()
cls.name = "MJPerson"
cls.isa = personMetaClass
cls.superClass = objectClass
return cls
}()
lazy var objectClass:ClassT = {
let cls = ClassT()
cls.name = "MJObject"
cls.isa = objectMetaClass
cls.superClass = nsObjectClass
return cls
}()
lazy var nsObjectClass:ClassT = {
let cls = ClassT()
cls.name = "MJNSObject"
cls.isa = nsObjectMetaClass
cls.superClass = nil
return cls
}()
// lazy var goodStudentMetaClass:ClassT = {
// let cls = ClassT()
// cls.name = "MJMetaGoodStudent"
// let cache = CacheT()
// cls.cache = cache
// let rw = ClassRwT()
// rw.methods = []
// cls.rw = rw
// cls.superClass = studentMetaClass
// return cls
// }()
lazy var studentMetaClass:ClassT = {
let cls = ClassT()
cls.name = "MJMetaStudent"
cls.superClass = personMetaClass
let cache = CacheT()
cls.cache = cache
let rw = ClassRwT()
rw.methods = []
cls.rw = rw
return cls
}()
lazy var personMetaClass:ClassT = {
let cls = ClassT()
cls.name = "MJMetaPerson"
cls.superClass = objectMetaClass
let cache = CacheT()
cls.cache = cache
let rw = ClassRwT()
rw.methods = []
cls.rw = rw
return cls
}()
lazy var objectMetaClass:ClassT = {
let cls = ClassT()
cls.name = "MJMetaObject"
cls.superClass = nsObjectMetaClass
let cache = CacheT()
cls.cache = cache
let rw = ClassRwT()
rw.methods = []
cls.rw = rw
return cls
}()
lazy var nsObjectMetaClass:ClassT = {
let cls = ClassT()
cls.name = "MJMetaNSObject"
let cache = CacheT()
cls.cache = cache
let ro = ClassRoT()
let method = MethodT()
method.name = NSSelectorFromString("alloc")
method.imp = "实现了alloc方法"
let methodList = MethodListT()
methodList.methodList = [method]
ro.baseMethodList = [methodList]
let rw = ClassRwT()
rw.methods = ro.baseMethodList
cls.rw = rw
return cls
}()
class func alloc(){
}
func getNoMetaClass(clsName:String) -> ClassT?{
// if clsName == "MJMetaGoodStudent" {
// return goodStudentClass
// }else
if clsName == "MJMetaStudent" {
return studentClass
}else if clsName == "MJMetaPerson" {
return personClass
}else if clsName == "MJMetaObject" {
return objectClass
}else if clsName == "MJMetaNSObject" {
return nsObjectClass
}else{
return nil
}
}
}
网友评论