Ios 使用NSOperationQueue在UIScrollView中加载远程服务器映像
我想用NSOperationQueue在UIScrollView的远程服务器中加载一些映像。因为如果我用普通的NSURL、NSData或NSMutableURLRequest加载它,那么加载所有图像需要花费太多的时间。之后,我在UIButton中显示这些图像。这是我的密码:Ios 使用NSOperationQueue在UIScrollView中加载远程服务器映像,ios,objective-c,uiscrollview,nsoperationqueue,nscache,Ios,Objective C,Uiscrollview,Nsoperationqueue,Nscache,我想用NSOperationQueue在UIScrollView的远程服务器中加载一些映像。因为如果我用普通的NSURL、NSData或NSMutableURLRequest加载它,那么加载所有图像需要花费太多的时间。之后,我在UIButton中显示这些图像。这是我的密码: - (void)viewDidLoad { [super viewDidLoad]; [self startAnimation:nil]; self.imageDownloadingQueue =
- (void)viewDidLoad
{
[super viewDidLoad];
[self startAnimation:nil];
self.imageDownloadingQueue = [[NSOperationQueue alloc] init];
self.imageDownloadingQueue.maxConcurrentOperationCount = 4; // many servers limit how many concurrent requests they'll accept from a device, so make sure to set this accordingly
self.imageCache = [[NSCache alloc] init];
[self performSelector:@selector(loadData) withObject:nil afterDelay:0.5];
}
-(void) loadData
{
adParser = [[AdParser alloc] loadXMLByURL:getXMLURL];
adsListArray = [adParser ads];
displayArray = [[NSMutableArray alloc] init];
for (AdInfo *adInfo1 in adsListArray)
{
AdInfo *adInfo2 = [[AdInfo alloc] init];
[adInfo2 setBannerIconURL:adInfo1.bannerIconURL];
[adInfo2 setBannerIconLink:adInfo1.bannerIconLink];
[displayArray addObject:adInfo2];
}
[self loadScrollView];
[activityIndicator stopAnimating];
}
-(void) loadScrollView
{
[self.scrollView setScrollEnabled:YES];
[self.scrollView setContentSize:CGSizeMake([displayArray count] * ScrollerWidth, ScrollerHight)];
for (int i = 0; i < [displayArray count]; i++)
{
adButtonOutLet = [[UIButton alloc] initWithFrame:CGRectMake(i*320, 0, ButtonWidth, ButtonHight)];
currentAd = [displayArray objectAtIndex:i];
NSString *imageUrlString = [currentAd bannerIconURL];
UIImage *cachedImage = [self.imageCache objectForKey:imageUrlString];
if (cachedImage)
{
[adButtonOutLet setImage:cachedImage forState:UIControlStateNormal];
}
else
{
[self.imageDownloadingQueue addOperationWithBlock:^
{
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrlString]];
UIImage *image = nil;
image = [UIImage imageWithData:imageData];
// add the image to your cache
[self.imageCache setObject:image forKey:imageUrlString];
// finally, update the user interface in the main queue
[[NSOperationQueue mainQueue] addOperationWithBlock:^
{
[adButtonOutLet setImage:image forState:UIControlStateNormal];
}];
}];
}
adButtonOutLet.userInteractionEnabled= YES;
[adButtonOutLet setTag:i];
[adButtonOutLet addTarget:self action:@selector(goToURL:) forControlEvents:UIControlEventTouchUpInside];
[self.scrollView addSubview:adButtonOutLet];
}
}
谁能告诉我上面的代码有什么问题吗?从远程服务器解析或检索数据没有问题。我通过NSLog检查它。我认为NSOperationQueue有一些问题,我无法正确管理。提前谢谢。如果你需要更多的信息,我会在这里附上。
祝你有一个愉快的一天。不确定这是你的问题还是你的解决方案,如果不测试自己,很难判断 取自 addOperationWithBlock:如果您有一个简单的操作 如果需要子类化,可以使用块创建操作 应用程序编程接口。如果要从块的外部参照任何对象, 记住,你应该传递一个弱引用。还有,如果你愿意的话 要执行与块中的UI相关的操作,必须执行该操作 在主线程上:
你的adButtonOutLet是一个类变量吗?这意味着您只有一个按钮已初始化,并在屏幕上UIScrollView@JasperPol谢谢你的评论。是的,我将其声明为属性@property strong,非原子ibuibutton*adButtonOutLet;,但是如果是这样的话,当我运行代码时,模拟器中应该至少显示一个按钮,不是吗?但是什么都没有。此外,在常规方式下使用NSURL和NSData所有按钮在scrollView中正确显示。那有什么问题吗谢谢你的解决方案。是的,如果我获取一个额外的UIImageView并在其中加载图像,创建MyViewController的弱引用,它绝对有效;。但问题是,这里我想在UIButton中加载所有图像作为子视图,然后按钮作为子视图添加到scrollView中。在这种情况下,创建MyViewController的弱引用有什么好处?当我将最终图像作为UIButton的输入时,它根本不显示图像:我认为,如果不使用类iVar,而只使用循环中的alloc和init按钮,那么就不必使用对UIViewController的弱引用。我真的看不出为那个按钮设置类iVar有什么意义。
// Create a weak reference
__weak MyViewController *weakSelf = self;
// Add an operation as a block to a queue
[myQueue addOperationWithBlock: ^ {
NSURL *aURL = [NSURL URLWithString:@"http://www.somewhere.com/image.png"];
NSError *error = nil;
NSData *data = [NSData dataWithContentsOfURL:aURL options:nil error:&error];
UIImage *image = nil;
If (data)
image = [UIImage imageWithData:data];
// Update UI on the main thread.
[[NSOperationQueue mainQueue] addOperationWithBlock: ^ {
weakSelf.imageView.image = image;
}];
}];