How to convert a delegate-based callback system into block-based?

僤鯓⒐⒋嵵緔 提交于 2020-01-03 11:45:02

问题


I have a class, which has a delegate based system for sending different type of requests. it uses delegate to tell the object when the request is complete and also if it was a success o an error.

Now, I also have to check what type of request was it in response to take appropriate action.

I have wrapper class that should give me a block based interface for the same.

I pass a completion-block and an error-block to a request method which should internally use this delegate based class.

And when the response comes, should automatically call the appropriate handler for that request type and depending on success and error as well.

I saw a similar question on SO, but it was a little unclear to me, So please give a general idea of how to go about it instead of marking it as duplicate straight away.


回答1:


Here is one way to do it. Use this RAExpendable class to dynamically build a delegate with a block based implementation.

Let's say your delegate is:

@protocol XDelegate
-(void) foo:(id)response;
@end

Add RAExpendable.h, RAExpendable.m from https://github.com/evadne/RAExpendable to your project. Dynamically add the delegate method:

    RAExpendable *expendable = [RAExpendable new];
    [expendable addMethodForSelector:@selector(foo:) types:"v@:@" block:^(id x, SEL sel, id response){
        NSLog(@"response is %@", response);
    }];

And set the expendable class as your delegate:

    someObject.delegate = expendable;

Now, if you do this:

    [expendable performSelector:@selector(foo:) withObject:@"OK"];

You get the string response is OK. Replace NSLog with whatever success/failure implementation you see fit. From now on, when you call foo:, the block executes instead.

If you want to modify this for your use case, note that the parameters for this example were v@:@, which according to the Type Encoding guide of the runtime means: void return, self, SEL, object. self and SEL are the two hidden parameters present on every Objective-C methods, the third parameter is the first non hidden parameter of the method. The signature of the block has to match the signature of the method.




回答2:


With REKit, you can make a delegate dynamically like below:

id dynamicDelegate;
dynamicDelegate = [[NSObject alloc] init];
[dynamicDelegate respondsToSelector:@selector(foo:) withKey:nil usingBlock:^(id receiver, id response) {
    NSLog(@"response is %@", response);
}];
someObject.delegate = dynamicDelegate;


来源:https://stackoverflow.com/questions/14155878/how-to-convert-a-delegate-based-callback-system-into-block-based

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!