您当前的位置:首页 > 计算机 > 编程开发 > Lua

Lua 函数转 OC Block

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

我们知道 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"})
)

自动测试 中的更多示例。

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