How do I return an NSError object from a delegate method?

I am developing a delegate method that is called when the remote server requires input from the delegate. The delegate at this point is responsible for filling in the data that should be sent to the server, and also informs the server if there is an error at this point.

Now I have a delegate method:

-(void)server:(MBServer*)server
 willSendData:(NSMutableString*)data
        error:(NSError**)error;

      

At this point, the delegate can provide data to the sending server by modifying the passed NSMutableString. Alternatively, it can raise an NSError to send back by setting the variable error

to a new NSError instance.

The problem with this is that the delegate method can be called from another thread via NSInvocation. The delegate can create a new NSError object, but it will be auto-implemented on the current thread until another thread receives a response.

In a single-threaded application, this won't be a problem because the delegate can just save the response right away, but I can't do that in a multi-threaded project (again because the current event loop will auto-class it). The delegate MUST store the error in order for the delegate to clear it.

This is for a public api and I don't like the idea of ​​requesting through the documentation that developers know they have to store the error object. It seems too dangerous.

// You *must* retain the returned error before
// passing it back or you will crash

-(void)server:(MBServer*)server
 willSendData:(NSMutableString*)data
        error:(NSError**)error;

      

Other ideas I was thinking were to send an NSError as a return value (seems somewhat non-standard since most of the methods return bool and take an NSError double pointer). It also looks strange.

-(NSError *)server:(MBServer*)server
      willSendData:(NSMutableString*)data;

      

I was also thinking about passing a volatile dictionary and asking the delegate to fill in the error. The dictionary will then save the error by reliably returning it to streams.

// Send your NSError response in the dictionary with the key
// MBServerErrorResponseKey

-(void)server:(MBServer*)server
 willSendData:(NSMutableString*)data
     response:(NSMutableDictionary*)response;

      

Has anyone dealt with this design problem and if so what was your solution?

Thanks.

0


a source to share


2 answers


How about this: instead of calling the delegate method directly, call the trampoline method via NSInvocation. The trampoline (which you would do) will just call the delegate method and save the error before returning. In other words, a trampoline (which would probably be a method on your server) would just transfer the call to the delegate with the arguments passed, then save the error and return.



+3


a source


One thing you could do is try something like

-(void)server:(MBServer*)server
 willSendData:(NSMutableString*)data
        shouldStop:(BOOL*)stopFlag;
-(NSError*)getLastErrorForServer:(MBServer*)server;

      



This will allow the delegate to signal the server that something went wrong by setting stopFlag

, and then the server can call a method getLastErrorForServer:

to get what actually went wrong. It might also make sense to make the method server:WillSendData:

return BOOL

instead of being passed as a pointer.

0


a source







All Articles