美文网首页
[iOS] BeeHive 学习笔记的学习

[iOS] BeeHive 学习笔记的学习

作者: manajay | 来源:发表于2018-06-07 13:51 被阅读83次
    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] BeeHive 学习笔记的学习

          本文链接:https://www.haomeiwen.com/subject/dzkgsftx.html