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