LuaWax引擎,Lua目录下是Lua解释器的源代码,用于解析运行Lua脚本;Wax目录下是Wax框架的源代码.
1. 为什么可以使用Wax Lua
OC是一门动态语言,可以在运行时动态的创建一个类。先看一下平常是如何创建一个类:
@interface UILabel : UIView <NSCoding>
父类:UIView
类名:UILabel
协议:NSCoding
我们也可以用动态的方式创建一个类:
父类
superClass = obj_getClass(superClassName)
创建类
Class cls= objc_allocateClassPair(superClass, className,0)
objc_registerClassPair(cls)
增加变量
class_addIvar(cls, name, size, alignment, types)
增加方法(getter和setter)
class_addMethod(cls, sel, imp, types)
增加协议
class_addProtocol(cls, protocol)
2. Wax的框架
Wax有两个重要的bridge:Lua bridge和Objective-C bridge。
Lua bridge:辅助Lua调用OC
a. 创建类
b. 创建类的实例对象
c. 调用OC类的方法
d. 内存管理
e. 类型转换Lua -> OC
Objective-C bridge:辅助OC调用Lua
a. 调用Lua类的方法
b. 类型转换 OC -> Lua
3. 类的创建
a. 获取父类
superClass = objc_getClass(superClassName)
b. 根据类名创建类
klass = objc_allocateClassPair(superClass, className, 0);
c. 增加wax变量,用于标记是否为wax创建的类
class_addIvar(klass, "wax_instance_userdata", size, alignment, "*");
d. 注册类
objc_registerClassPair(klass);
e. 重写getter和setter方法(处理OC与Lua数据的类型转换)
class_addMethod(klass, @selector(setValue:forUndefinedKey:), (IMP)setValueForUndefinedKey, "v@:@@");
将key:value转为Lua类型,再压入到wax的栈上保存
class_addMethod(klass, @selector(valueForUndefinedKey:), (IMP)valueForUndefinedKey, "@@:@");
将wax上的value取出并转为OC类型返回
f. 在元类中重写alloc方法(标记是否为wax创建的类)
id metaclass = object_getClass(klass); (获取元类)
Method m = class_getInstanceMethod(metaclass, @selector(allocWithZone:));
class_addMethod(metaclass, @selector(wax_originalAllocWithZone:), method_getImplementation(m), method_getT ypeEncoding(m));
class_addMethod(metaclass, @selector(allocWithZone:), (IMP)allocWithZone, "@@:^{_NSZone=}");
在allocWithZone中设置wax_instance_userdata的值为YEAP
g. 添加协议
class_addProtocol(klass, protocol)
4. 实例对象的创建
根据类名获取类对象objc_getClass,然后通过alloc和init创建。
alloc方法:调用时加入到弱表,并将引用计数加一
init方法:如果是类方法,将引用计数加一
5. 类方法的调用
6. wax对OC对象的内存管理
7. 引用计数管理
增加引用计数:wax_instance_create创建类对象时,引用计数加一。
wax_instance_create的使用场景
a. 创建class object,引用class object。
b. 调用lua写的实例方法时,如果实例对象不在弱表中,对应的实例对象引用计数加一,否则引用计数不变。
c. lua调用类方法时,类对象引用计数不变。
d. lua调用类方法时,如果该方法为init方法,则引用计数加一,并标记为autoAlloc。
减少引用计数:下一个消息循环时,如果当前内存值超过阈值,则开始将持有对象的引用计数减一
8. 类型转换
int wax_fromObjc:将OC类型转为lua类型并压入lua栈
void *wax_copyToObjc:从lua栈上取出,并将lua类型转为OC类型
类型包括:
a. void,pointer,short,char,int,unsigned int,long,float等基础类型
b. NSString,NSArray,NSDictionary,NSValue,WaxFunction,Class等id类型
c. struct
d. selector
9. Objective-C bridge的功能模块
wax api:wax的初始化、启动、停止
wax class:类的创建,以及协议的添加
wax instace:实例的创建,并将创建的实例放入强表和弱表
wax gc:定时清理不用的强表数据
wax helpers:lua类型和oc类型的转换,debug信息输出,错误处理
wax server:网络操作
wax struct:wax结构数据的定义和操作
wax stdlib:打包的lua bridge脚本
10. Lua bridge的功能模块
Enums:oc宏定义,lua不能直接使用oc的宏定义,需要将oc常用的enum在lua中重新定义。
waxClass:根据className、superclassName、protocols创建类
Structs:oc的struct定义,如CGSize,NSRange等
Helpers:工具方法,包括cache,base64,time等
Ext:基础类型(number、string、table、http)的常用方法