QQ邮箱记事本模块Lua实现小结

本文总结了QQ邮箱记事本模块使用Lua实现的原理,包括借助Wax引擎实现Lua与Objective-C交互,以及多线程、OC调用Lua代码的自动化生成、调试方法、数据库操作优化和代码下发更新策略。同时分享了在实现过程中的经验教训,如nil值检查、数组索引、Block处理和中文字符串长度计算等。
摘要由CSDN通过智能技术生成

QQ邮箱是一个除了收邮件和发邮件的基本功能之外,具有其它一些小的办公功能的邮箱客户端。其中记事本是办公功能之一。
但是集成了记事本等小功能的邮箱,体积较大。为控制客户端体积,需要将非基本功能的一些功能模块脚本化,不编译到App当中,达到控制App体积,修复和升级方便的目的。
本文包括3个部分:

  • 原理简介
  • 优化经验
  • 教训

原理简介

Lua作为一门脚本语言,借助Lua脚本引擎和Lua运行库,来解释执行Lua脚本。我们选择Wax作为Lua引擎,来执行Lua。它利用Objective-c Runtime的特性,在Lua脚本中调用OC的类和方法。Wax由probablycorey创建,目前由阿里团队负责维护。
Wax引擎原理在于:
Wax包含一个Lua的解释器和运行库,从而能解释执行标准Lua脚本;
Wax扩充了Lua的语法,为Lua调用OC类及OC类动态添加方法提供了基础。
使用Lua实现的优势(参考此链接):

  1. 自动垃圾收集 无需手动创建对象,即无需用alloc方法进行对象的初始化工作;
  2. 更少的代码 无需头文件,不用static类型、数组和逐字化声明字典;
    使用Lua能调用每一个Cocoa,UITouch,Foundation等类和框架;这种调用OC类的能力也为功能模块使用Lua脚本实现提供了基础。
  3. Lua使用closure来替代OC中的Blocks
  4. 内置正则匹配库
  5. 超简单的HTTP 请求
  6. 动态下发和执行
    Lua代码可以作为资源文件下发到app端,然后在app端进行动态执行。从而能够减少app安装包的体积,并能动态发布和维护代码。邮箱的记事本模块目前采用此模式,后面会详解。

优化经验

1. 多线程和锁

分析Lua引擎和Wax框架,锁会在下述情况下产生:
a. Lua底层api对运行上下文lua_State加的锁
b. Wax框架在C和Lua数据交换时,为保证线程安全所加的锁
解决方案:
使用Lua协程,或者用Lua协程配合iOS的GCD框架,使得父协程和子协程在不同的空间中运行,从而支持竞争式多协程。
Lua框架本身并不支持多线程,但OC中很多情况下得使用多线程,所以在OC转换成Lua的过程中,需要让Lua支持多线程才能做到和原生OC写的效果一致。解决方案是利用协程,配合GCD达到多线程的效果。

介绍一下自己的LUA封装 1: C++中的类可以注册到LUA 中,在LUA里面可以使用像C++一样使用对象调用函数一样 2: 将C或者C++中的函数注册到LUA中,在LUA里面直接调用全局函数 3: 加载LUA文件并且执行,执行LUA文件中的某个函数。 会自动平衡LUA堆栈,使用的时候不需要担心LUA栈的问题 4: 可以将LUA中的某个函数作为回调函数,当条件满足时调用回调函数 .................. 这篇就介绍一下怎样在LUA中使用C++的类对象 //说明一下::带有LRT_ 的函数都是自己封装的,在LUA 库里面是没有的 --下面是main 函数 int _tmain(int argc, _TCHAR* argv[]) { //获取LUA 运行状态 lua_State *l = LRT_GetLuaState(); //注册C++类 RegisterLuaClass::RegisterClass(l); char current_dir[260] = {0}; DWORD ret = GetCurrentDirectory(260, current_dir); std::string strTmp(current_dir); std::stringstream strS; strS<<strTmp<<"\\LuaClassTest.lua"; //加载一个LUA文件,只是加载了,并没有执行,一定要返回成功了才可以 LRT_RunChunk if (LRT_ErrorCode_Success == LRT_CreateChunkFromFile(l,strS.str().c_str())) { LRT_RunChunk(l); } strS.clear(); strS.str(""); strS<<strTmp<<"\\dataStruct.lua"; if (LRT_ErrorCode_Success == LRT_CreateChunkFromFile(l,strS.str().c_str())) { LRT_RunChunk(l); } getchar(); return 0; } --下面是LUA文件中代码 --获取C++对象,参数为 类型的名称,这个名称和C++的名称对应 local object = LRTGetObject("Test.Lua.Class") --调用对象的函数 object:Fun1() object:Fun2()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值