-
Notifications
You must be signed in to change notification settings - Fork 781
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BHService的生命周期Issue #107
Comments
@RylanJIN When you use ServiceManager to create a Service instance, you finally get the instance from the return value, every time, a different instance. So, obviously you should take control of the instance life cycle. the Manager is like a Factory. When use singleton, you should never think about this, because the singleton instance of a service will live for App life cycle after first created (the actual creation) by ServiceManager and you always get the same instance when you request ServiceManager for an instance of a singleton Service. Reading the code, you'll see. |
@MemoryReload Thanks for you kind explanation, however, I am wondering if it is necessary to maintain a singleton instance even if you only use this service just for one time? But if I don't use singleton instance there seems no way to workaround the block issue which I mentioned above. Any suggestions? thanks again. |
@RylanJIN Let's think about this , If you want to maintain the block for after use, first your ShopModuleService instance maybe, should copy the block and save as a property. If you just use it in fetchDataWithCompletion: method lifecycle, it's not needed. As foresee, If your service module is gone, your block will gone too. So, first solution is that you maintain the returned ShopModuleService instance until the block executes. Second one is simple, just turning your ShopModuleService into a singleton. In a nutshell, it's all up to you to decide how you manage what your service to be. |
@MemoryReload Thanks again for your inspired discussion. As you point out: [first solution is that you maintain the returned ShopModuleService instance until the block executes]. How can I achieve this? Shouldn't lifecycle of the service instance be maintained by the BeeHive? In my opinion, your second option is the only way to fix my situation. Welcome further response. |
@RylanJIN read this code from - (id)createService:(Protocol *)service
{
id implInstance = nil;
if (![self checkValidService:service]) {
if (self.enableException) {
@throw [NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"%@ protocol does not been registed", NSStringFromProtocol(service)] userInfo:nil];
}
}
NSString *serviceStr = NSStringFromProtocol(service);
id protocolImpl = [[BHContext shareInstance] getServiceInstanceFromServiceName:serviceStr];
if (protocolImpl) {
return protocolImpl;
}
Class implClass = [self serviceImplClass:service];
if ([[implClass class] respondsToSelector:@selector(singleton)]) {
if ([[implClass class] singleton]) {
if ([[implClass class] respondsToSelector:@selector(shareInstance)])
implInstance = [[implClass class] shareInstance];
else
implInstance = [[implClass alloc] init];
[[BHContext shareInstance] addServiceWithImplInstance:implInstance serviceName:serviceStr];
return implInstance;
}
}
return [[implClass alloc] init];
} If your service class is not singleton, the service manager only do what factory do, it just create a new instance of the service class and return it to you. It's your job to handle the instance life cycle. maybe you should make a strong reference to it until the block finish its job, because your instance gone, your block gone too (block is a special kind of object, you should know). However the singleton service is treated specially, as you can see above, the BHContext strongly referred it, and managed it for you. Do I made it clear? |
@RylanJIN There's a neat way, but in high risk. you can make your block refer your returned service instance. Here is a retain cycle: your service instance retains your block, and your block retains your service. the reason to do this is you don't want to adopt your service instance. In this way, your block will keep your service instance from being destroyed, although no other objects strong referred to it. |
@MemoryReload I guess you mean something like this: id<ShopModuleServiceProtocol> shopService = [[BeeHive shareInstance] createService:@protocol(ShopModuleServiceProtocol)];
[shopService fetchDataWithCompletion:^(NSData *data) {
// to do...
}]; RETAIN instance 'shopService' till completion block gets exerted. e.g. define a global variable and assigned with shopService, then set it to nil in completion block to allow its release. Nevertheless, I am looking for a solution (which maybe provided by BeeHive I do not aware of) that dispense with this extraneous and fussy calls. Really appreciate your communication, buddy! |
@RylanJIN As far as I know, BeeHive doesn't provide life cycle control strategy for un-singleton service. It's all up to you. And I mean you can do the neat way without fussy global variables, maybe as simple as this: id<ShopModuleServiceProtocol> shopService = [[BeeHive shareInstance] createService:@protocol(ShopModuleServiceProtocol)];
//block will retain your service and take the life cycle control
__block id<ShopModuleServiceProtocol> myService = shopService;
[shopService fetchDataWithCompletion:^(NSData *data) {
// do whatever you like ...
//break the retain cycle, let the service destroyed.
myService = nil;
}]; This is maybe a little bit confusing. But It should work, I think. It will ensure that your service will not be destroyed until the end of your block execution. |
@MemoryReload Well noted, thanks for you patient explanation! |
@RylanJIN Glad to talk to you, dude. : ) |
two chinese speak english,哈哈! |
@sususu You think we're stupid and funny, don't you? |
没,我很羡慕你们的英语水平,英语国际化,为了让更多人看得懂吗,但是国内看不懂英语的还是很多,如果是兼顾更多人,我觉得用中文的话,帮助更大; |
@sususu Maybe, you're right. No matter like it or not, just enjoy. : ) |
@RylanJIN @MemoryReload use English 👍 PS |
如果某个service的提供方的接口返回数据是block形式返回的,比如:
这时很有可能completion返回的时候ShopModuleService已经被释放了,所以这个时候必须要在ShopModuleService这么设置吗:
也就是说为了等一个completion返回(也许这个接口只调用一次)就必须让ShopModuleService的对象一直存在,一直不释放?
请问是这样的理解的吗,或者说这个问题可以有其他的解决办法?期待回复,谢谢!
The text was updated successfully, but these errors were encountered: