Lua userdata资源释放
首先来一段PIL中的说明: Life is not always that easy. Sometimes,an object needs other resources besides raw memory,such as file descriptors,window handles,and the like. (Often these resources are just memory too,but managed by some other part of the system). In such cases,when the object becomes garbage and is collected,somehow those other resources must be released too. Several OO languages provide a specific mechanism (called?finalizer?or?destructor) for that need. Lua provides finalizers in the form of the? ??? 假设现在我们需要写一个遍历目录的库,遍历文件基本流程是: findFile ? -> 打开一个编译句柄 nextFile ?-> 遍历目录中的文件 closeFind -> 遍历完成 ? 在lua使用遍历目录库: for name in dir(path) do .... end ? 注意:dir是库中注册进去的API,支持for in 泛型语法。跟进Lua要求,需要dir返回一个迭代器(必须),可选的返回状态变量和控制变量。 如果for name in dir(path) do ... end 完全执行完毕,中间不会退出或者中断,那么不用考虑太多问题。但是如果中间会退出呢?比如说,编译某个目录,查找文件名为A的文件,如果找到了就退出。大致lua代码如下: for name in dir(path) do if (name == A) then return end end ? 由于遍历需要通过findFile打开一个查询句柄,我们需要显示的释放此句柄。类似 查找进程、打开文件等等都是如此,分配的系统资源必须在不用的时候释放。 回到上面的问题,如何保证打开的查下句柄能正常释放呢?利用userdata的__gc metathod。 lua中的userdata在被回收的时候,会调用其__gc metathod方法。如是乎,我们只需要为__gc写一个metathod方法即可实现。 1、定义一个简单数据结构,用于遍历目录保存查询句柄和一些额外信息: ? ? ? 2、定义我们的dir函数 ? ? 3、定义真正的迭代函数dir_iter
4、定义我们的清理函数
5、OK,现在可以注册dir了
6、别忘了,还有create_dir_metatable,这个主要目的是增加__gc metatable
? 注意,上面的宏定义使用了2中方法。 如果定义了宏RETURN_ITERFUN_AND_STATUS,dir返回迭代器dir_iter和状态变量; 如果没有定义RETURN_ITERFUN_AND_STATUS宏,dir只返回迭代器函数,参数作为迭代器函数的upvalue携带过去。 两种方式都能达到泛型遍历的效果。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |