2014-09-08 2 views
0


Я хочу загрузить некоторое «изображение» (на удаленном сервере) в UIScrollView с NSOperatoinQueue. Потому что, если я загружаю его с нормальным NSURL, NSData или с NSMutableURLRequest, для загрузки всех изображений требуется слишком много времени. После этого я показываю эти изображения в UIButton. Вот мой код:Загрузить изображение удаленного сервера в UIScrollView с NSOperatoinQueue

- (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 есть некоторые проблемы, с которыми я не могу справиться должным образом. Заранее спасибо. Если вам нужна дополнительная информация, я приложу сюда. Имейте славный день.

+0

Ваш adButtonOutLet является переменной класса? Это означало бы, что у вас есть только 1 кнопка инициализирована и на вашем UIScrollView – Jasper

+0

@JasperPol Спасибо за комментирование. Да, я объявляю его как свойство '@property (сильный, неатомный) IBOutlet UIButton * adButtonOutLet;', но если это так, когда я запускаю код, должна быть хотя бы одна кнопка, отображаемая в симуляторе, не так ли ? Но ничего нет. Кроме того, регулярно используя кнопку 'NSURL' и' NSData', все кнопки отображаются правильно в 'scrollView'. Тогда что с этим не так? :( – Tulon

ответ

0

Не уверен, что это ваша проблема или ваше решение, ее трудно сказать, не испытывая себя.

Взятые из RayWenderlich

addOperationWithBlock: если у вас есть простая операция, которая не нужно быть подклассы, вы можете создать операцию, используя блок API. Если вы хотите ссылаться на какой-либо объект извне в блоке, то помните, что вы должны перейти в слабую ссылку. Кроме того, если вы хотите сделать что-то, что связано с UI в блоке, вы должны сделать это на главной теме:

// 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; 
    }]; 

}]; 
+0

Спасибо за решение. И да, он абсолютно работает, если я беру Extra 'UIImageView' и загружаю изображение там, создавая слабую ссылку« MyViewController »(' __weak MyViewController * weakSelf = self; '). я хочу загрузить все мое изображение в 'UIButton' как subView, а затем Button добавлены в' scrollView' как 'subView'. В этом случае хорошо что создать слабую ссылку на MyViewController? Когда я возьмите окончательный «образ» в качестве ввода моего «UIButton», который не показывает изображения вообще. :( – Tulon

+0

Я думаю, что если бы вы не использовали класс iVar, а просто выделили и запустили кнопки внутри цикла, вам не пришлось бы использовать слабая ссылка на ваш UIViewController. Я вообще не вижу смысла в том, что для этой кнопки есть класс iVar. – Jasper

Смежные вопросы