iphone - iOS设计: Using the delegate pattern in a library

标签 iphone design-patterns delegates ios

我有一个库项目,它使用 ASIHTTPRequest 发出 URL 请求并解析响应。该库将由单独的 iPhone 应用程序项目使用。

如果我的 iPhone Controller 代码响应触摸事件,然后调用库以发出 URL 请求,我如何最好地异步执行请求?

在库中,如果我使用 ASIHTTPRequest 示例代码中所示的异步请求委托(delegate)模式,如何将数据从库返回到 iPhone Controller 中的调用代码?

如果我在库内使用 ASIHTTPRequest 发出同步 URL 请求,那么将 iPhone Controller 对库的调用放在单独的线程上以避免占用 UI 线程的最简单方法是什么?

最佳答案

我不是 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 明确建议您使用内置的运行循环样式机制进行异步 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"];
}

如果你不考虑线程化,可能会犯大约一百万次并发错误,在该示例中,一个明显的问题是,无论触发 IBAction 的是什么,都可以在 doExpectiveOperationOn 完成之前多次触发它。多线程不是可以轻易投入的东西。

关于iphone - iOS设计: Using the delegate pattern in a library,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3962502/

相关文章:

c# - Windows服务设计

c# - 设计简单模拟器时的设计考虑

c++ - 酒店预订系统的面向对象设计

ios - UIStackView 在 Swift 中没有成员委托(delegate)错误

c# - 与多个事件发布者和多线程关联的单个 .NET 事件订阅者

iphone - WordPress 博客 iPhone 应用程序阅读器

iphone - 实时调整粒子文件(.plist)

swift - 快速使用委托(delegate)将字符串从一个 View Controller 发送到另一个 View Controller

iphone - NSScrollView 具有未剪辑的内容 View ?

iphone - UIPickerView - 更改组件宽度