//
// CategoryBasementViewController.swift
// iOS底层
//
// Created by yanqunchao on 2019/5/17.
// Copyright © 2019 yanqunchao. All rights reserved.
//
import UIKit
class CategoryBasementViewController: UIViewController {
/**
* 方法类
*/
class MethodT: NSObject {
var name:String?
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 ClassT: NSObject {
var isa:ClassT? //指针
var superClass:ClassT? //父类
var cache:NSObject? //方法缓存
var ro:ClassRoT? //只读类
var rw:ClassRwT? //可读可写类
var isRealized:Bool = false //附加信息,标志是否已经处理过分类
}
/**
* 分类对象
*/
class CategoryT: NSObject {
var name:String = "" //所属类的名称
var cls:ClassT? //所属类对象
var instanceMehthodList:MethodListT? // 实例方法列表
var classMethodList:MethodListT? //类方法列表
var proptocolList:[String]? //协议列表
var propList:[String]? //属性列表
}
lazy var categoryArr:[CategoryT] = []
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .white
//获取所有分类
getAllCategory()
for cat in self.categoryArr { //遍历分类列表
let cls = cat.cls //获取到所属类
if cls?.isRealized == false {
remethodizeClass(cls: cls!) //对所属类重新方法化
}
}
}
//对所属类重新方法化
func remethodizeClass(cls:ClassT) {
let cats = unattachCategoriesForClass(cls: cls) //分类归类
if cats.count > 0 {
attachCategoriesForClass(cls: cls, cats: cats) //合并分类到类中
}
}
//合并分类到所属类中
func attachCategoriesForClass(cls:ClassT,cats:[CategoryT]){
cls.isRealized = true
var methodArrList:[MethodListT] = []
var i = cats.count
while (i != 0) {
let cat = cats[i - 1]
let methodList = cat.instanceMehthodList
methodArrList.append(methodList!)
i = i - 1
}
let oldMethods = cls.rw?.methods?.first
methodArrList.append(oldMethods!)
//// let oldCount = oldMethods?.count
//// let newCount = methodArrList.count + oldCount!
//
cls.rw?.methods = methodArrList
}
//从分离列表中剥离所属类的分类
func unattachCategoriesForClass(cls:ClassT) ->[CategoryT] {
var categroyT:[CategoryT] = []
for cat in self.categoryArr { //遍历分类列表
if cls.ro?.name == cat.cls?.ro?.name {
categroyT.append(cat)
}
}
return categroyT
}
//获取所有分类
func getAllCategory(){
let baseMethod = MethodT()
baseMethod.name = "base"
baseMethod.type = "v16@0:8"
baseMethod.imp = "MJPerson的base方法地址"
let baseMethodT = MethodListT()
baseMethodT.size = 1000
baseMethodT.methodCount = 1
baseMethodT.methodList = [baseMethod]
let ro = ClassRoT()
ro.baseMethodList = [baseMethodT]
ro.name = "MJPerson"
let cls = ClassT()
cls.isa = ClassT()
cls.superClass = ClassT()
cls.cache = NSObject()
cls.ro = ro
let rw = ClassRwT()
rw.ro = ro
rw.methods = ro.baseMethodList
cls.rw = rw
let testMethod = MethodT()
testMethod.name = "test"
testMethod.type = "v16@0:8"
testMethod.imp = "MJPerson的test方法地址"
let eatMethod = MethodT()
eatMethod.name = "eat"
eatMethod.type = "v16@0:8"
eatMethod.imp = "MJPerson的eat方法地址"
let testMethodList = MethodListT()
testMethodList.size = 1000
testMethodList.methodCount = 1
testMethodList.methodList = [testMethod]
let eatMethodList = MethodListT()
eatMethodList.size = 1000
eatMethodList.methodCount = 1
eatMethodList.methodList = [eatMethod]
let categoryTest:CategoryT = CategoryT()
categoryTest.name = "MJPerson"
categoryTest.cls = cls
categoryTest.instanceMehthodList = testMethodList
let categoryEat:CategoryT = CategoryT()
categoryEat.name = "MJPerson"
categoryEat.cls = cls
categoryEat.instanceMehthodList = eatMethodList
let cls1 = ClassT()
cls1.isa = ClassT()
cls1.superClass = ClassT()
cls1.cache = NSObject()
let baseMethod1 = MethodT()
baseMethod1.name = "base"
baseMethod1.type = "v16@0:8"
baseMethod1.imp = "MJAnimal的base方法地址"
let baseMethodT1 = MethodListT()
baseMethodT1.size = 1000
baseMethodT1.methodCount = 1
baseMethodT1.methodList = [baseMethod1]
let ro1 = ClassRoT()
ro1.baseMethodList = [baseMethodT1]
ro1.name = "MJAnimal"
cls1.ro = ro1
let rw1 = ClassRwT()
rw1.ro = ro1
rw1.methods = ro1.baseMethodList
cls1.rw = rw1
let testMethod1 = MethodT()
testMethod1.name = "test"
testMethod1.type = "v16@0:8"
testMethod1.imp = "MJAnimal的test方法地址"
let eatMethod1 = MethodT()
eatMethod1.name = "eat"
eatMethod1.type = "v16@0:8"
eatMethod1.imp = "MJAnimal的eat方法地址"
let testMethodList1 = MethodListT()
testMethodList1.size = 1000
testMethodList1.methodCount = 1
testMethodList1.methodList = [testMethod1]
let eatMethodList1 = MethodListT()
eatMethodList1.size = 1000
eatMethodList1.methodCount = 1
eatMethodList1.methodList = [eatMethod1]
let categoryTest1:CategoryT = CategoryT()
categoryTest1.name = "MJAnimal"
categoryTest1.cls = cls1
categoryTest1.instanceMehthodList = testMethodList1
let categoryEat1:CategoryT = CategoryT()
categoryEat1.name = "MJAnimal"
categoryEat1.cls = cls1
categoryEat1.instanceMehthodList = eatMethodList1
self.categoryArr.append(categoryTest1)
self.categoryArr.append(categoryTest)
self.categoryArr.append(categoryEat)
self.categoryArr.append(categoryEat1)
}
}
iOS原理之Category的实现原理
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- Category的本质 Demo首先我们写一段简单的代码,之后的分析都基于这段代码。 我们之前讲到过实例对象的is...
- 分类在我们的项目中经常被使用到,它是给现有的类添加方法,也可用于根据功能划分模块,今天我们就来研究一下分类实现的原...
- 开篇之前大家先思考这两个问题 Category的实现原理?Category和Extension的区别是什么?Cla...