IOS Design: Using the Delegate Template in the Library

I have a library project that uses ASIHTTPRequest to create URL requests and parse responses. The library will be used by a separate iPhone application project.

If my iPhone controller code responds to a touch event, then calls up a URL request in the library, what is the best way to execute requests asynchronously?

In the library, if I use the delegate template for asynchronous requests, as shown in the ASIHTTPRequest example, how can I return data from the library back to the calling code in the iPhone controller?

If I instead do synchronous URL requests with ASIHTTPRequest inside the library, what is an easy way to put calls to the library from the iPhone controller in a separate thread to avoid binding the UI thread?

+2
source share
2 answers

For any future reference, the simplest approach I have found is to use the async request function built into ASIHTTPRequest, set my library object as a delegate, and set the values ​​of didFinishSelector: and didFailSelector: different methods inside my library for each request.

At the end of processing each response, I pass the processed response (NSString * or NSArray *) to the property of my library object instead of returning a value.

iOS , , . , observValueForKeyPath: ofObject: change: context:, , , , .

+1

ASIHTTPRequest (NSURLRequest ), , , delegate didFinishSelector, - , URL- . , :

- (void)startURLRequest
{
    ASIHTTPRequest *myRequest;

    /* code to set the request up with your target URL, etc here */

    myRequest.delegate = self;
    myRequest.didFinishSelector = @selector(HTTPRequestDidFinish:);

    /* ... */

    [myRequest startAsynchronous];
}

- (void)HTTPRequestDidFinish:(ASIHTTPRequest *)request
{
    NSLog(@"Request %@ did finish, got data: %@", request, request.data);
    [myTargetForData didReceiveData:request.data fromURL:request.originalURL];
}

Apple runloop HTTP, . , , - , / , .

, , , - (: UIKit ),

- (void)postResult:(NSString *)result
{
    instanceOfUILabel.text = result;
}

- (void)doExpensiveOperationOn:(NSString *)source
{
     /* lots of expensive processing here, and then... */
     [self postResult:result];
}

- (IBAction)userWantsOperationDone:(id)sender
{
     [self doExpensiveOperationOn:@"some value or another"];
}

:

- (void)postResult:(NSString *)result
{
    instanceOfUILabel.text = result;
}

- (void)doExpensiveOperationOn:(NSString *)source
{
     /* we're on a thread without an autorelease pool now, probably we'll want one */
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

     /* lots of expensive processing here, and then... */

     /* in this simplified example, we assume that ownership of 'result' is here on this thread, possibly on the autorelease pool, so wait until postResult has definitely finished before doing anything that might release result */
     [self performSelectorOnMainThread:@selector(postResult:) withObject:result waitUntilDone:YES];

     [pool release];
}

- (IBAction)userWantsOperationDone:(id)sender
{
     [self performSelectorOnBackgroundThread:@selector(doExpensiveOperationOn:) withObject:@"some value or another"];
}

concurrency, , threaded, , , , IBAction, [] , doExpensiveOperationOn . - -, .

+2

All Articles