Coder Social home page Coder Social logo

alibaba / beehive Goto Github PK

View Code? Open in Web Editor NEW
4.3K 165.0 782.0 441 KB

:honeybee: BeeHive is a solution for iOS Application module programs, it absorbed the Spring Framework API service concept to avoid coupling between modules.

Home Page: https://github.com/alibaba/BeeHive/blob/master/README.md

License: GNU General Public License v2.0

Objective-C 98.32% C 0.85% Ruby 0.83%
beehive registered-services modular ios service module service-discovery service-registration lifecycle lifecycle-events

beehive's Issues

v1.2.0 关于BHContext的疑问

先前通过继承BHContext来定义了一个CustomContext来存放公共环境变量,例如服务器环境,服务器基址等信息。

问题

v1.2.0版本代码有些改动,BHModuleManager类以及BHServiceManager类内部对于plist静态模块加载plist静态服务加载模块生命周期事件触发均是引用[BHContext shareInstance]对象,然而BHAppDelegate中对于touchShortcutItemopenURLItemnotificationsItemuserActivityItem等属性的赋值却是针对于 [BeeHive shareInstance].context的。

结论

结论就是说我们在使用plist进行模块或者服务的静态注册是我们需要使用[BeeHive shareInstance]来配置plist的路径,而对于touchShortcutItemopenURLItemnotificationsItemuserActivityItem等属性的取值我们要使用CustomContext。这是否与BeeHive的设计初衷不一致?

这英文写的太烂。。

如果真的是阿里员工写的话,多找几个英文好的读读帮改改。这语句主谓宾组织太写意。动词名词从句各种乱入。逻辑表达前后含混不清。。

Service 跟 Module 有什么区别

[BHContext shareInstance].moduleConfigName = @"BeeHive.bundle/BeeHive";//可选,默认为BeeHive.bundle/BeeHive.plist
[BHContext shareInstance].serviceConfigName = @"BeeHive.bundle/BHService";

代码中看到的,请问Service 跟 Module 有什么区别呢?谢谢

Service返回对象类型声明的建议

id<UserTrackServiceProtocol> v4 = [[BeeHive shareInstance] createService:@protocol(UserTrackServiceProtocol)];
if ([v4 isKindOfClass:[UIViewController class]]) {
    [self registerViewController:(UIViewController *)v4 title:@"埋点3" iconName:nil];
}

id的具体类型需要项目间约定,能否在Protocol的声明文件中就标注返回类型是什么?
比如做约定:

#import <Foundation/Foundation.h>
#import "BHServiceProtocol.h"

@class UIViewController;  //表示当前协议返回类型为UIViewController
@protocol UserTrackServiceProtocol <NSObject,BHServiceProtocol>

@end

毕竟Protocol只能绑定一种类型。

建议将BeeHive类的registerDynamicModule:方法改为私有

  1. 用户如果通过调用registerDynamicModule:方法实现模块注册的话,其调用时机必须在设置BHContext上下文之前,这样容易造成用户调用时机不对而导致模块注册失败。
  2. 官方文档中提到模块注册也只说了2种,静态注册、宏(BH_EXPORT_MODULE),宏BH_EXPORT_MODULE定义中调用了registerDynamicModule:方法,所以我建议将registerDynamicModule:私有,以免误操作。至于宏中调用的话,可以修改一下宏BH_EXPORT_MODULE的定义。

关于 BHServiceProtocol 单例的疑问

BHServiceProtocol 中定义了shareInstance这个方法,那么我通过 createService: 获取一个单例对象的时候,为什么单例对象不是通过我实现的方法创建?

Class implClass = [self serviceImplClass:service];
Method clzSingleMethod = class_getInstanceMethod(implClass, @selector(singleton));
Method insSingleMethod = class_getClassMethod(implClass, @selector(singleton));
if (clzSingleMethod == NULL &&
    insSingleMethod == NULL) {
    return [implClass new];
}

implInstance = [[implClass alloc] init];
NSString *serviceStr = NSStringFromProtocol(service);
[[BHContext shareInstance] addServiceWithImplInstance:implInstance serviceName:serviceStr];
return implInstance;

在上面 BHServiceManagercreateService: 实现中,只是判断了是否实现了 singleton 方法,然后是通过 [[implClass alloc] init] 创建的单例。

通过BeeHiveService声明的Service找不到

  1. 首先,AppDelegate继承了BHAppDelegate,回调书写如Demo中一样
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    [BHContext shareInstance].application = application;
    [BHContext shareInstance].launchOptions = launchOptions;
    [BHContext shareInstance].moduleConfigName = @"PPDDemoHome.bundle/PPDDemoHomeModule";//可选,默认为BeeHive.bundle/BeeHive.plist
    [BHContext shareInstance].serviceConfigName = @"PPDDemoHome.bundle/PPDDemoHomeService";
    
    [BeeHive shareInstance].enableException = YES;
    [[BeeHive shareInstance] setContext:[BHContext shareInstance]];
    [[BHTimeProfiler sharedTimeProfiler] recordEventTime:@"BeeHive::super start launch"];
    
    [super application:application didFinishLaunchingWithOptions:launchOptions];
  1. 新建一个PPDUserViewController 实现PPDUserServiceProtocol,
#import <Foundation/Foundation.h>
#import <BeeHive/BeeHive.h>

@protocol PPDUserServiceProtocol <NSObject, BHServiceProtocol>

@end
#import "PPDUserViewController.h"
#import "PPDUserServiceProtocol.h"

BeeHiveService(PPDUserServiceProtocol, PPDUserViewController)
@interface PPDUserViewController ()<PPDUserServiceProtocol>

@end

@implementation PPDUserViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
  1. 在BHReadConfiguration读取声明配置的时候memory为NULL,导致获取不到声明的Service
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;
    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;
    
}
  1. 但是通过MachOView找到section地址,再在Hopper中能够找到数据

wx20170314-191155 2x

wx20170314-191222 2x

BHReadConfiguration 提供 framework 支持

目前只能在静态链接下 work。

Podfile 中添加 use_frameworks!,以动态库的形式安装 pod 的话,dladdr(BHReadConfiguration, &info); 读取到的 image 就是 BeeHive.framework 了,而 compile 时的 BeeHiveService(HomeServiceProtocol,BHViewController) 则将 info 写在了代码所在 image 的 __DATA 中(可能是主 app 的 executable,也可能是其他的 framework)。

因此需要针对这种情况进行支持,BHReadConfiguration(char *section) 应该需要多接收一个 const void* addr,然后在前面想办法把 addr 传入\找出。

BH_EXPORT_MODULE中async永远返回YES

BHModuleProtocol.h中define BH_EXPORT_MODULE(isAsync)
+ (void)load { [BeeHive registerDynamicModule:[self class]]; } \
-(BOOL)async { return (BOOL)**#isAsync;**} 

这里的#isAsync表示加个引号,就算是BH_EXPORT_MODULE(NO) (BOOL) async {return (BOOL)"NO";}
返回永远为YES

CocoaPods 1.0 support

{:exclusive=>true} is an unsupport option in CocoaPods 1.0 version.Please fix it.

2个文档说明的改进

ReadMe中@property(nonatomic, readonly) BHEnvironmentType env;这个属性
直接set了但是明明是个readonly,

另外,文档中[BHContext shareInstance].env = BHEnvironmentDev; 这行代码等号是个全角等号

非单例service生命周期

service创建的时候会加入到servicesByName的dictionary中,但是service不再使用的时候并不能及时的dealloc,而是在下一个同样的service创建的时候进行的dealloc,这样会增加一些service本身的资源开销。

能否增加协议在模块出口处释放资源?

关于registedAnnotationModules和registerAnnotationServices

想知道一下这两个注册模块和服务的方法,还有这这种实现的原理,

#define BeeHiveDATA(sectname) __attribute((used, section("__DATA,"#sectname" ")))



#define BeeHiveMod(name) \
char * k##name##_mod BeeHiveDATA(BeehiveMods) = ""#name"";

#define BeeHiveService(servicename,impl) \
char * k##servicename##_service BeeHiveDATA(BeehiveServices) = "{ \""#servicename"\" : \""#impl"\"}";
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;
    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;
        
        NSLog(@"config = %@", str);
        if(str) [configs addObject:str];
    }
    
    return configs;
    
}

service调用为什么不用URL的形式

现在协议的方式,还是有一些耦合度。
用协议的实现方式也有你们自己的想法,
我想知道当时为什么没有用URL的调用方式?
还是现在正在策划中?

project.xcworkspace 文件

我注意到 BeeHive.xcodeproj 目录下的 project.xcworkspace 没有被包含进项目中,我想了解,不把project.xcworkspace 纳入版本控制的原因是什么?

在引入BeeHive的工程里,一些组件的配置应该放在那个地方呢?

比如我们目前的工程里,一些组件需要外部环境参数配置,目前是放在 didFinishLaunchingWithOptions 里,然后项目依赖这些组件。在引入BeeHive后,这些组件的合适位置应该是放在那里?是应该作为Module 一样,每个组件都创建一个Module 管理组件的生命周期,还是只建一个公共Module 统一管理这些组件?

另外,麻烦再问下,每个项目做成插件后,独立运行的基础是 项目代码依赖一个统一的工程配置吗?比如说各种组件的初始化配置,都放在一个工程壳子里,然后每个项目代码加上这个壳子就能独立编译运行

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.