2025年4月12日 星期六 乙巳(蛇)年 正月十三 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Lua

Lua 函数转 OC Block

时间:12-14来源:作者:点击数:2

我们知道 OC block 是一个 NSObject,而 block 对应 wax 中的 WaxFunction,所以如果我们知道 block 的参数类型,我们就可以构造 block。

在 armv7/i386 中,参数在栈中的地址很简单,char,int,BOOL,pointer,id 可以看成 int,所以我们可以使用可变参数函数来构造一个块。(参见  wax_block_transfer.m)如:

  • - (LongLong (^)(int p, ...))luaBlockReturnLongLongWithFirstIntParamTypeEncoding:(NSString *)paramsTypeEncoding{
  • return [[^LongLong(int q, ...){
  • LUA_BLOCK_CALL_ARM32_RETURN_BUFFER(paramsTypeEncoding, LongLong, q);
  • } copy] autorelease];
  • }

在 arm64/x86_64 中,事情变得更难了,但有些我们将 char,int,BOOL,pointer,id,long 其视为 longlong,并将 float,double 其视为 double,因此可以生成具有 510 个函数的块池以支持具有最多 7 个不同类型参数的块。(参见 wax_block_transfer_pool.m)

  • 您可以使用 toblock(luaFunction, typeArray) 将 Lua 函数转换为 OC Block。typeArray 中的第一项必须是返回值类型(返回 void 且没有参数的块除外)。(toblock 是 luaBlockWithParamsTypeArray 的封装,见 lib/stdlib/ext/block.lua)
  • 空块,返回空块
  • UIView:animateWithDuration_animations_completion(1,
  • toblock(
  • function()
  • label:setCenter(CGPoint(300, 300))
  • end
  • ),
  • toblock(
  • function(finished)
  • print('lua animations completion ' .. tostring(finished))
  • end
  • ,{"void", "BOOL"})-- return void
  • )
  • - (void)testReturnIdWithFirstIdBlock:(id(^)(id aFirstId, BOOL aBOOL, int aInt, NSInteger aInteger, float aFloat, CGFloat aCGFloat, id aId))block
  • local res = self:testReturnIdWithFirstIdBlock(
  • toblock(
  • function(aFirstId, aBOOL, aInt, aInteger, aFloat, aCGFloat, aId)
  • print("lua aFirstInt")
  • return "123"
  • end
  • , {"id", "id", "BOOL", "int", "NSInteger" , "float" , "CGFloat" , "id" })
  • )
  • 避免保留循环只使用一次块
  • --OC block void (^)(UIViewController * sourceViewController, UIWebView * webView);
  • local weakSelf = self--temp self
  • self:setMyblock(
  • toblock(
  • function(sourceViewController, webView)
  • -- print("lua sourceViewController")
  • print(string.format("lua sourceViewController=%s webView=%s self.price=%s", tostring(sourceViewController), tostring(webView), tostring(weakSelf:price())))
  • weakSelf = nil--make it empty
  • end
  • , {"void", "id", "id"})
  • )

多次使用块

  • local weak = {}
  • b = {__mode = "v"}
  • setmetatable(weak, b)
  • weak.self = self
  • toblock(
  • function(sourceViewController, webView)
  • -- print("lua sourceViewController")
  • print(string.format("lua sourceViewController=%s webView=%s self.price=%s", tostring(sourceViewController), tostring(webView), tostring(weakSelf:price())))
  • weak.self:xxx()
  • end
  • ), {"void", "id", "id"})
  • )

自动测试 中的更多示例。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐