×

[iOS] BeeHive 学习笔记的学习

96
manajay
2018.06.07 13:51* 字数 255
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段属于数据段
可以出一个连线题了哈哈.png

既然 被放入了数据段的 __DATA,""BeehiveMods BeehiveMods段中
那Module的取出方法?

static NSArray<NSString *>* 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。防止出现递归引起的线程安全问题。
?? 这里存在异步多线程调用吗, 为什么会加锁. 还是得看源码

iOS 开发
Web note ad 1