Re: [問題] Obj-C++ and template
推
09/21 23:13,
09/21 23:13
→
09/21 23:13,
09/21 23:13
推
09/23 03:33,
09/23 03:33
→
09/23 03:33,
09/23 03:33
→
09/23 03:33,
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)
→
09/24 01:21, , 1F
09/24 01:21, 1F
→
09/24 01:21, , 2F
09/24 01:21, 2F
→
09/24 01:21, , 3F
09/24 01:21, 3F
不知道你說搭配的 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
推
09/24 10:31, , 4F
09/24 10:31, 4F
沒特別研究別的 不過有空的話我再參考看看
Block-in-Block 只是一時興起的念頭
覺得這個 programming 方法有趣且應該有用 就開發來玩玩
※ 編輯: leondemon 來自: 114.198.184.235 (09/25 00:55)
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 3 之 3 篇):