作者leondemon (狗狗)
看板MacDev
标题Re: [问题] Obj-C++ and template
时间Tue Sep 24 00:39:17 2013
1F:推 Killercat:其实template block...我还真想不到哪里非用这种不可@@ 09/21 23:13
2F:→ Killercat:block其实就是lambda 就是个只需要用一次用过即丢的东西 09/21 23:13
3F:推 Killercat:这个我倒是很乐观clang会把它们整合在一起.... 09/23 03:33
4F:→ Killercat:不过我还是想不出有什麽原因会让你不用templated func 09/23 03:33
5F:→ Killercat:而非得搞个templated lambda不可 =P 09/23 03:33
在开发新的 programming 方式
最主要是让部分程式码以 block 包装
然後在一个 function/method 内 让这些 blocks 串在一起 (类似queue/chain)
然後从第一个 block 开始执行 并会在适当时机呼叫下一个 block
但也有可能不呼叫下一个 block 就立刻返回
目前已经开发差不多 (其实只有短短几行 code)
但是遇到如果 function 有 return 值的话
每个中间经手的 block 都必须要回传下一个 block 的回传值
直到最後没有 block 为止
通常最後一个 block 才是真正要执行的内容
而在执行最後一个 block 之前 可以先执行别的程式码
我先把主架构(目前称它为 Block-In-Block, BIB)的 code 贴上来:
===== Block-In-Block 主架构 =====
typedef void* (^BIBExecutionBlock)();
typedef BIBExecutionBlock (^BIBAdviceBlock)(BIBExecutionBlock executionBlock);
BIBExecutionBlock BIBHandler(BIBAdviceBlock advice, ...);
BIBExecutionBlock composeAdvices(BIBAdviceBlock headBlock, va_list tailBlocks);
BIBExecutionBlock BIBHandler(BIBAdviceBlock advice, ...){
va_list advices_list;
va_start(advices_list, advice);
BIBExecutionBlock composedBlock = composeAdvices(advice, advices_list);
va_end(advices_list);
return composedBlock;
}
BIBExecutionBlock composeAdvices(BIBAdviceBlock headBlock, va_list tailBlocks){
if (headBlock == nil) { return nil; }
return headBlock(composeAdvices(va_arg(tailBlocks, BIBAdviceBlock), tailBlocks));
}
========= 实作几个 AdviceBlock =========
AOPAdviceBlock advice_1 = ^AOPExecutionBlock(AOPExecutionBlock furtherBlock){
return ^void*(){
void *retVal = NULL;
printf("before advice_1\n");
// 若不呼叫 furtherBlock() 则不会执行下一个 block
retVal = furtherBlock();
printf("after advice_1\n");
return retVal;
};
};
AOPAdviceBlock advice_2 = ^AOPExecutionBlock(AOPExecutionBlock furtherBlock){
return ^void*(){
void *retVal = NULL;
printf("before advice_2\n");
retVal = furtherBlock();
printf("after advice_2\n");
return retVal;
};
};
=========== 实作两个 method 使用 advice_1/advice_2 ===========
@implementation BIBTest
+ (NSInteger) doubleTheNumber:(NSInteger)number{
return * (NSInteger*)BIBHandler(advice_1, advice_2,
^BIBExecutionBlock(BIBExecutionBlock furtherBlock){
return ^void*(){
NSLog(@"action");
NSInteger numberValue = number *2;
void *retVal = &numberValue;
return retVal;
};
}, nil)();
}
+ (NSString*) logConsole:(NSString*)string{
return (__bridge NSString *)(BIBHandler(advice_1, advice_2,
^BIBExecutionBlock(BIBExecutionBlock furtherBlock){
return ^void*(){
NSLog(@"action for string: %@", string);
NSString *newString = [NSString stringWithFormat:@"Hello, %@!",
string];
return (__bridge void *)(newString);
};
}, nil)());
}
@end
========== 在 main() 呼叫这两个 method ========
int main(int argc, char *argv[])
{
NSLog(@"%@", [BIBTest logConsole: @"Tom"]);
NSLog(@"====================");
NSLog(@"doubleTheNumber: %d", [BIBTest doubleTheNumber:50]);
}
=========== Console ============
> before advice_1
> before advice_2
> action for string: Tom
> after advice_2
> after advice_1
> Hello, Tom!
> ====================
> before advice_1
> before advice_2
> action
> after advice_2
> after advice_1
> doubleTheNumber: 100
目前在处理 block-in-block 的回传值问题 (应该还会牵扯到记忆体管理)
必须使用 void* 作为 BIBExecutionBlock 的回传值
并在 function/method 内要重新 cast 才能回传
希望可以自动判断回传型别 而不需要手动 cast
这个 progamming 的方式 可以让各 block 决定是否呼叫下一个 block
并且可以窜改後面 block 回传回来的值 (如果有必要的话)
因为目前 method 的实作 其实内部很多都是在做很多杂事
想把这些杂事转为 block 可以让 code 乾净很多
(当然还是得搭配 macro)
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 114.198.184.235
※ 编辑: leondemon 来自: 114.198.184.235 (09/24 01:01)
6F:→ Killercat:你说的很像COR Pattern(Chains of Responbility) 09/24 01:21
7F:→ Killercat:指的是这个吗?所以你需要一个block产生器? 09/24 01:21
8F:→ Killercat:噢搭macro的话....那可能能做的会比想像多很多... 09/24 01:21
不知道你说搭配的 marco 可以做的事有哪些
我已经有写好 macro 可以比较像叙述的语法来写 Code 会看起来比较简洁
目前就是卡在 block 的回传值要如何传递回去给 function 去 return
一直希望有解法至少可以看起来比较整洁一点... (如果可以用 Obj-C++ 解也OK)
这比较不像是责任链 责任链目的是要找到 responder 由它来负责处理 event
我的这个比较像是一个 hook 构造
假如 block 的排列顺序为 A -> B -> C -> D -> T(目标 block) ...
(後面还可以接其他 block)
则会执行 A -> B -> C -> D -> T -> D' -> C' -> B' -> A'
中间可以依判断而终止往後传而进行返回
例如 C 决定不呼叫下一个 block 则 A -> B -> C -> B' -> A'
搭配创造 block 的 method
9F:推 johnlinvc:感觉像是js 的future/promise或是 FP的monad 09/24 10:31
没特别研究别的 不过有空的话我再参考看看
Block-in-Block 只是一时兴起的念头
觉得这个 programming 方法有趣且应该有用 就开发来玩玩
※ 编辑: leondemon 来自: 114.198.184.235 (09/25 00:55)