[iOS]|[iOS] BeeHive 学习笔记的学习

  • BeeHive —— 一个优雅但还在完善中的解耦框架
image.png 好玩的点 宏的使用 Annotation方式注册
BeeHiveMod(ShopModule) #define BeeHiveMod(name) \ char * k##name##_mod BeeHiveDATA(BeehiveMods) = ""#name""; #define BeeHiveDATA(sectname) __attribute((used, section("__DATA,"#sectname" "))) // 结果 char * kShopModule_mod __attribute((used, section("__DATA,""BeehiveMods"" "))) = """ShopModule""";

__attribute
__attribute第一个参数used很有用。 这个关键字是用来修饰函数的。 被used修饰以后,意味着即使函数没有被引用,在Release下也不会被优化。 如果不加这个修饰,那么Release环境链接器下会去掉没有被引用的段。

程序源程序代码被编译之后会主要分成两个段:程序指令和程序数据。代码段属于程序指令,数据段和.bss段属于数据段

[iOS]|[iOS] BeeHive 学习笔记的学习
文章图片
可以出一个连线题了哈哈.png 【[iOS]|[iOS] BeeHive 学习笔记的学习】既然 被放入了数据段的 __DATA,""BeehiveMods BeehiveMods段中
那Module的取出方法?
static NSArray* BHReadConfiguration(char *section) { NSMutableArray *configs = [NSMutableArray array]; Dl_info info; dladdr(BHReadConfiguration, &info); #ifndef __LP64__ // const struct mach_header *mhp = _dyld_get_image_header(0); // both works as below line const struct mach_header *mhp = (struct mach_header*)info.dli_fbase; unsigned long size = 0; // 找到之前存储的数据段(Module找BeehiveMods段 和 Service找BeehiveServices段)的一片内存 uint32_t *memory = (uint32_t*)getsectiondata(mhp, "__DATA", section, & size); #else /* defined(__LP64__) */ const struct mach_header_64 *mhp = (struct mach_header_64*)info.dli_fbase; unsigned long size = 0; uint64_t *memory = (uint64_t*)getsectiondata(mhp, "__DATA", section, & size); #endif /* defined(__LP64__) */// 把特殊段里面的数据都转换成字符串存入数组中 for(int idx = 0; idx < size/sizeof(void*); ++idx){ char *string = (char*)memory[idx]; NSString *str = [NSString stringWithUTF8String:string]; if(!str)continue; BHLog(@"config = %@", str); if(str) [configs addObject:str]; }return configs; }

疑惑的地方
char *string = (char*)memory[idx]; // 这里的 idx 不用每次偏移 `sizeof(void*)` 的距离吗 还是没看懂这个结构啊

注册方式 分为三种
  • 本地plist
  • load 方式
注册对象: 必须遵守协议, 只有被 manager 管理,才能接收事件的分发
事件的分发
一般做法是把BHAppDelegate接管原来的AppDelegate。
注意这里所有的Module必须是遵循BHModuleProtocol的,否则无法接收到这些事件的消息。
业务自定义事件
- (void)triggerEvent:(BHModuleEventType)eventType { switch (eventType) { default: [BHContext shareInstance].customEvent = eventType; [self handleModuleEvent:kAppCustomSelector]; break; } }

BeeHive模块调用
在BeeHive中是通过BHServiceManager来管理各个Protocol的。BHServiceManager中只会管理已经被注册过的Protocol。
在存储allServices数组的时候,是要加锁的。这里的lock是NSRecursiveLock。防止出现递归引起的线程安全问题。
?? 这里存在异步多线程调用吗, 为什么会加锁. 还是得看源码

    推荐阅读