Reputation: 104135
I am writing a simple application using the Facebook iPhone SDK. The Facebook code is mostly asynchronous, I start an operation and receive the response asynchronously in a delegate call:
- (void) doSomething {
[FBSomething startOperationWithDelegate:self];
}
- (void) fbOperationFinished: (FBSomething*) operation {…}
Quite often there are more instances of a given operation (say FBRequest
) that use the same callback. This means that I have to put a conditional clause into the callback handler to know which of these operations finished.
This leads to messy, a kind of “asynchronous spaghetti code” monster because the code is full of conditionals and it’s almost impossible to see the program flow logic. Is there a better way to write such code? (It’s a shame we don’t have blocks on iPhone.) I thought about introducing a simple state machine, but I’m not sure it will help.
Upvotes: 4
Views: 870
Reputation: 75077
I would put these requests into an NSOperationQueue, this keeps each one distinct and also throttles how many you have active at once.
You just need to wrap the requests into an NSOperation object (which the Facebook API may have already?)
Upvotes: 0
Reputation: 34945
There is no need to subclass the Facebook API objects. I would highly recommend against that.
All the facebook objects have a userInfo
field that you can use to store request specific information. So you can store something in there to identify the request or even a reference to an object to deal with the request.
That is much cleaner and more in the style of the Cocoa frameworks.
Upvotes: 3
Reputation: 64428
(It’s a shame we don’t have blocks on iPhone.)
You can create a visual block using curly brackets without a symbol. For example, animation blocks have no visual structure but you can supply it like this:
// ...some code
[UIView beginAnimations:@"selectionAnimation" context:nil];{
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.1];
[UIView setAnimationRepeatCount:1];
[UIView setAnimationRepeatAutoreverses:YES];
{ //start properties to animate
self.transform=CGAffineTransformScale(self.transform, 1.1, 1.1);
} // end properties to animate
[UIView commitAnimations];
}
// more code...
It's not a logical block but it's better than nothing. You can also use them to fold code. I use them to hide assertions or debug code.
Upvotes: 1
Reputation: 7496
I'm not familiar with the Facebook SDK, but you could just create a subclass that implements the FBRequestDelegate
protocol (if it's called like that) for every specific task you need Facebook for. This way, you have say 5 classes implementing - fbOperationFinished:
rather than one class with 5 different execution paths separated by if
s or switch
es.
Upvotes: 10