gpt4 book ai didi

ios - 使用 block 跟踪异步连接

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:13:50 26 4
gpt4 key购买 nike

我正在做很多 URL 请求(大约 60 张小图片),我已经开始异步处理它们。我的代码添加了另一张图片(很少下载),然后设置了一个请求。

请求完成后,我希望将“数据”放在最初为它添加的位置,但是,我看不到如何将“imageLocation”传递给 block ,以便它在正确的位置存储图像位置。

我已将第 3 行替换为下面这似乎有效,但我不是 100% 正确(很难判断,因为图像几乎相同)。我还认为可以在声明 block 的位置传递“imageLocation”。

任何人都可以证实这一点吗?

__block int imageLocation = [allImages count] - 1;

  // Add another image to MArray
[allImages addObject:[UIImage imageNamed:@"downloading.png"]];
imageLocation = [allImages count] - 1;

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
[request setTimeoutInterval: 10.0];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue currentQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

if (data != nil && error == nil)
{
//All Worked
[allImages replaceObjectAtIndex:imageLocation withObject:[UIImage imageWithData:data]];

}
else
{
// There was an error, alert the user
[allImages replaceObjectAtIndex:imageLocation withObject:[UIImage imageNamed:@"error.png"]];

}];

最佳答案

处理异步方法很痛苦;)

在您的情况下,它保证完成 block 将在指定队列上执行。但是需要保证队列最大并发数为1,否则并发访问共享资源是不安全的。那是一场经典的比赛http://en.wikipedia.org/wiki/Race_condition .可以使用属性设置 NSOperationQueue 的最大并发操作数。

通常,完成处理程序可以在任何线程上执行,除非另有说明。

使用称为“Promises”的概念时,处理异步方法变得容易得多 http://en.wikipedia.org/wiki/Promise_(programming) .基本上,“Promises”表示将在未来评估的结果——尽管如此,promise 本身是立即可用的。类似的概念被命名为“futures”或“deferred”。

GitHub 上有一个 Objective-C 中的 promise 实现:RXPromise。使用它时,您还可以从处理程序 block 内安全访问共享资源。实现如下所示:

-(RXPromise*) fetchImageFromURL:(NSString*)urlString queue:(NSOperationQueue*) queue
{
@autoreleasepool {
RXPromise* promise = [[RXPromise alloc] init];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
[NSURLConnection sendAsynchronousRequest:request
queue:queue
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (data != nil) {
[promise fulfillWithValue:data];
}
else { // There was an error
[promise rejectWithReason:error];
};
}];
return promise;
}
}

然后调用它:

- (void) fetchImages {

...

for (NSUInteger index = 0; index < N; ++index)
{
NSString* urlString = ...
[self fetchImageFromURL:urlString, self.queue]
.then(^id(id data){
[self.allImages replaceObjectAtIndex:index withObject:[UIImage imageWithData:data]];
return @"OK";
},
^id(NSError* error) {
[self.allImages replaceObjectAtIndex:index withObject:[UIImage imageNamed:@"error.png"]];
return error;
});
}
}

关于ios - 使用 block 跟踪异步连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16732747/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com