我们知道 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)
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
)
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"})
)
自动测试 中的更多示例。

