gpt4 book ai didi

iphone - 调用 NSURLConnectionDataDelegate 方法来下载图像只是偶尔有效

转载 作者:行者123 更新时间:2023-12-01 19:08:48 26 4
gpt4 key购买 nike

我的 Storyboard目前有两个 UIImageView ,其中一个下载我自己的 Facebook 个人资料图片,另一个下载 friend 的个人资料图片。

Storyboard layout

但是,我的问题是 仅 60% 的时间按预期工作 ,而其他 40% 的时间我自己的个人资料图片出现在我 friend 的图片应该显示在底部的位置,而顶部的框仍然是空的。我不确定这是否是我在下载或完成 View 时调用 NSURLConnectionDataDelegate 方法的结果,还是我调用 Facebook 的请求的性质。

我在 viewDidLoad 中将我的两个请求的精简版粘贴到 Facebook,一个获取我自己的个人资料照片,另一个获取我 friend 的照片:

// ----- Gets my own profile picture, using requestForMe -----
FBRequest *request = [FBRequest requestForMe];
[request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
//handle response
if(!error){
//Some methods not included for breveity, includes facebookID used below
NSURL *pictureURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://graph.facebook.com/%@/picture?type=large&return_ssl_resources=1", facebookID]];
self.imageData = [[NSMutableData alloc] init];
switcher = 1;
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:pictureURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:2.0f];
NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
if (!urlConnection){
NSLog(@"Failed to download picture");
}
}
}];
// ----- Gets a profile picture of my friend, using requestForMyFriends -----
FBRequest *requestForFriends = [FBRequest requestForMyFriends];
[requestForFriends startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if(!error){
//Other methods not included, including facebookFriendID
NSURL *friendPictureURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://graph.facebook.com/%@/picture?type=large&return_ssl_resources=1", facebookFriendID]];
self.supportImageData = [[NSMutableData alloc] init];
switcher = 2;
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:friendPictureURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:2.0f];
NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
if (!urlConnection){
NSLog(@"Failed to download picture");
}
}
}];

这两个请求都调用了 NSURLConnectionDataDelegate 方法,我使用 switcher 来决定何时加载哪张图片:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// As chuncks of the image are received, we build our data file

if (switcher == 1) [self.imageData appendData:data];
if (switcher == 2)[self.supportImageData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{

//When the entire image is finished downloading
if (switcher == 1) {
UIImage *image = [UIImage imageWithData:self.imageData]; //puts the completed picture into the UI
self.titleImageView.image = image;
[self.titleImageView setClipsToBounds:YES];
}

if (switcher == 2) {
UIImage *supportImage = [UIImage imageWithData:self.supportImageData];
self.supportImageView.image = supportImage;
[self.titleImageView setClipsToBounds:YES];
}
}

最佳答案

您有两个异步进程,这两个进程都可能导致您的 NSURLConnectionDataDelegate self 中的方法被调用。但如果它们同时发生,它们就会相互叠加(您可能正在使用单个 NSMutableData 变量来引用正在下载的数据)。

要么创建专用类,您可以为两个 NSURLConnection 中的每一个实例化一次。请求(基于 NSOperation 的方法,如 AFNetworking 是理想的),或使用 sendAsynchronousRequest 反而。但不要使用单个对象作为 delegate两个并发NSURLConnection同时提出要求。

如果你想看一个极简的下载操作,它可能看起来像:

//  NetworkOperation.h

#import <Foundation/Foundation.h>

typedef void(^DownloadCompletion)(NSData *data, NSError *error);

@interface NetworkOperation : NSOperation

- (id)initWithURL:(NSURL *)url completion:(DownloadCompletion)completionBlock;

@property (nonatomic, copy) NSURL *url;
@property (nonatomic, copy) DownloadCompletion downloadCompletionBlock;

@end


//  NetworkOperation.m

#import "NetworkOperation.h"

@interface NetworkOperation () <NSURLConnectionDataDelegate>

@property (nonatomic, readwrite, getter = isExecuting) BOOL executing;
@property (nonatomic, readwrite, getter = isFinished) BOOL finished;
@property (nonatomic, strong) NSMutableData *data;

@end

@implementation NetworkOperation

@synthesize finished = _finished;
@synthesize executing = _executing;

- (id)initWithURL:(NSURL *)url completion:(DownloadCompletion)downloadCompletionBlock
{
self = [super init];
if (self) {
self.url = url;
self.downloadCompletionBlock = downloadCompletionBlock;

_executing = NO;
_finished = NO;
}
return self;
}

#pragma mark - NSOperation related stuff

- (void)start
{
if ([self isCancelled]) {
self.finished = YES;
return;
}

self.executing = YES;

NSURLRequest *request = [NSURLRequest requestWithURL:self.url];
NSAssert(request, @"%s: requestWithURL failed for URL '%@'", __FUNCTION__, [self.url absoluteString]);
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
[connection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[connection start];
}

- (void)setExecuting:(BOOL)executing
{
[self willChangeValueForKey:@"isExecuting"];
_executing = executing;
[self didChangeValueForKey:@"isExecuting"];
}

- (void)setFinished:(BOOL)finished
{
[self willChangeValueForKey:@"isFinished"];
_finished = finished;
[self didChangeValueForKey:@"isFinished"];
}

- (BOOL)isConcurrent
{
return YES;
}

#pragma mark NSURLConnectionDataDelegate methods

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
self.data = [NSMutableData data];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
if ([self isCancelled]) {
[connection cancel];
self.executing = NO;
self.finished = YES;
return;
}

[self.data appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
if (self.downloadCompletionBlock) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.downloadCompletionBlock(self.data, nil);
self.downloadCompletionBlock = nil;
}];
}

self.executing = NO;
self.finished = YES;
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
if (self.downloadCompletionBlock) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.downloadCompletionBlock(nil, error);
self.downloadCompletionBlock = nil;
}];
}

self.executing = NO;
self.finished = YES;
}

@end

然后,当你想使用它时,它可能看起来像:
NSOperationQueue *networkQueue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 4;

// ----- Gets my own profile picture, using requestForMe -----
FBRequest *request = [FBRequest requestForMe];
[request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
//handle response
if(!error) {
//Some methods not included for breveity, includes facebookID used below
NSURL *pictureURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://graph.facebook.com/%@/picture?type=large&return_ssl_resources=1", facebookID]];

[networkQueue addOperation:[[NetworkOperation alloc] requestWithURL:pictureURL completion:^(NSData *data, NSError *error) {
if (!error) {
self.meImageView.image = [UIImage imageWithData:data];
}
}]];
}
}];
// ----- Gets a profile picture of my friend, using requestForMyFriends -----
FBRequest *requestForFriends = [FBRequest requestForMyFriends];
[requestForFriends startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
if(!error){
//Other methods not included, including facebookFriendID
NSURL *friendPictureURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://graph.facebook.com/%@/picture?type=large&return_ssl_resources=1", facebookFriendID]];

[networkQueue addOperation:[[NetworkOperation alloc] requestWithURL:friendPictureURL completion:^(NSData *data, NSError *error) {
if (!error) {
self.friendImageView.image = [UIImage imageWithData:data];
}
}]];
}
}];

关于iphone - 调用 NSURLConnectionDataDelegate 方法来下载图像只是偶尔有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18173669/

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