Ehtesham Hasan Ehtesham Hasan -4 years ago 105
Objective-C Question

Storing a parameter value to be returned later in delegate callback

I have a singleton class and a protocol defined as below. (Simplified)

@protocol ClassADelegate <NSObject>

- (void) classADelegateDidFinishSomething:(BOOL) aBool;


@interface ClassA : NSObject

@property (nonatomic, weak) id<ClassADelegate> delegate;

+ (ClassA *) shared;
- (void) methodA:(BOOL) aBool;


method causes a chain of asynchronous callbacks internally and finally in a private method needs to call the delegate method like the following way.

if (self.delegate)
[self.delegate classADelegateDidFinishSomething:BOOL_FROM_methodA];

in the above method must be the same as the
in the
method. So I have to store the value of the
somewhere. Lets say I store it in a private variable
like the following and later using this to call the delegate method.

- (void) classMethodA:(BOOL) aBool
_aBool = aBool;

- (void) aPrivateMethod

if (self.delegate)
[self.delegate classADelegateDidFinishSomething:_aBool];

This solves the problem if it was guaranteed that no further calls to
is done before the delegate method is called. But imagine the following situation.

[[ClassA shared] methodA:YES];
[[ClassA shared] methodA:NO];

For the above code, both of the
callbacks will have
as their parameter value, even though the 1st
call has
as its parameter.

I would like to get an elegant solution to the problem without refactoring most of my code.

Answer Source

You're implementing something that requires context (multiple requests) using structures that are inherently one-to-one (singleton, delegate). This isn't a good match.

Options that come to mind are to use a unique instance of ClassA for each invocation of methodA or to rewrite ClassA methods so that the caller supplies its own context.

For example:

- (void)classMethodA:(BOOL)aBool listener:(id<ClassADelegate>)listener;

That way, you could map each call to the object that made it.

Or, if there's only one delegate making multiple calls, replace the listener object with any kind of context parameter that can be used to tag the calls.

- (void)classMethodA:(BOOL)aBool context:(id)context;
- (void)aPrivateMethod:(id)context;

For either of those options, your singleton can maintain a collection that maps calls to responses.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download