iphone — выполняет выборочную загрузку фонового изображения

#iphone #uiscrollview

#iPhone #uiscrollview

Вопрос:

я загружаю изображения в UIView внутри UIScrollView, используя performSelectorInBackground для извлечения изображений из URL. Изображения правильно загружаются в массив, но когда я присваиваю UIImageView эти изображения, все изображения назначаются последней странице прокрутки.

 @implementation DetailViewController

- (id)initWithDataSource:(id<TabBarElementProtocol,UITableViewDataSource>)theDataSource {
    if ([self init]) {


        // Scroll View 
        scrollView = [[UIScrollView alloc]init];

        //a page is the width of the scroll view

        scrollView.delegate = self;
        scrollView.pagingEnabled = YES;
        scrollView.frame = CGRectMake(0, 0, 320, 300);
        scrollView.contentSize = CGSizeMake(320*10, 300);
        scrollView.backgroundColor = [UIColor clearColor];
        scrollView.showsHorizontalScrollIndicator = NO;
        scrollView.showsVerticalScrollIndicator = NO;
        scrollView.scrollsToTop = NO;
        scrollView.bounces = NO;
        scrollView.showsHorizontalScrollIndicator = NO;

        scrollView.pagingEnabled = YES;

        [self.view addSubview:scrollView];

        scrollView.contentOffset = CGPointMake(10*320, 0);

        [self displayView];

    }
    return self;
}




-(void) displayView{
    DouglasAppDelegate *delegate = (DouglasAppDelegate *)[[UIApplication sharedApplication] delegate];


    for (int i=0; i < 10; i  )
    {

        myview = [[UIView alloc] init];
        myview.frame = CGRectMake(320*i , 0, 320, 300);
        [myview setBackgroundColor: [UIColor whiteColor]];


        pictureImageView = [[UIImageView alloc] initWithFrame:CGRectMake(179, 11, 100, 100)];
        pictureImageView.tag = i;
        [myview addSubview: pictureImageView];
        [pictureImageView release];
// Picture URL is accessed dynamically and loading correctly.
        [dataArray insertObject:[NSMutableArray arrayWithObjects:picUrl,[NSString stringWithFormat:@"%d", i],nil]       atIndex:i];


        [scrollView addSubview:myview];

    }

    [self performSelectorInBackground:@selector(loadImageInBackground:) withObject:dataArray];


    //Pager control

    tpageControl                    = [[UIPageControl alloc] initWithFrame:CGRectMake(0, 300 , 320, 17)];
    tpageControl.backgroundColor    = [UIColor clearColor]; 
    tpageControl.numberOfPages      = [delegate.NeuEntries count];
    tpageControl.currentPage        = delegate.neuDetailIndex;
    zumPage                         = delegate.neuDetailIndex ;
    [tpageControl addTarget:self action:@selector(pageTurn:) forControlEvents:UIControlEventValueChanged];
    [self.view addSubview: tpageControl];

}


- (void) loadImageInBackground:(NSMutableArray *)urlAndTagReference  {

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSData *imgData;
    UIImage *img;
    NSMutableArray *arr1 = [[NSMutableArray alloc] initWithCapacity: [urlAndTagReference count]];

    for(int i=0; i<[urlAndTagReference count] ;i  )
      {
            NSString *url = [[urlAndTagReference objectAtIndex:i] objectAtIndex:0];  
            NSURL *imgURL = [NSURL URLWithString:url];      
            imgData = [NSData dataWithContentsOfURL:imgURL];
            img = [[UIImage alloc] initWithData:imgData];
            [arr1 insertObject:[NSMutableArray arrayWithObjects:img,[[urlAndTagReference objectAtIndex:i]objectAtIndex:1],nil] atIndex:i];

    }   

    [self performSelectorOnMainThread:@selector(assignImageToImageView:) withObject:arr1 waitUntilDone:YES];
}



- (void) assignImageToImageView:(NSArray *)imgAndTagReference
{

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];


     for(int i=0; i<[imgAndTagReference count] ;i  ){

            UIImage *img = [[UIImage alloc] init];
            img = [[imgAndTagReference objectAtIndex:i] objectAtIndex:0];
            NSLog(@"img %@",img);
            // SAME IMAGES OVERLAPPING ON LAST PAGE OF SCROLL VIEW????????????????
            [pictureImageView setImage:img];
         }



}


- (void) pageTurn:(UIPageControl*) aPageController{

    int whichPage                   = aPageController.currentPage;
    scrollView.contentOffset        = CGPointMake(320.0f * whichPage, 0.0f);

}



- (void)scrollViewDidScroll:(UIScrollView *)sender
{

    CGPoint offset              = sender.contentOffset;
    tpageControl.currentPage    = offset.x / 320.0f;


}
  

Ответ №1:

В следующей строке вы создаете утечку памяти

 UIImage *img = [[UIImage alloc] init];
img = [[imgAndTagReference objectAtIndex:i] objectAtIndex:0];
  

Вам не нужно выделять и инициализировать новое UIImage, просто установите для него значение во второй строке.

Во время зацикливания изображений вы устанавливаете все изображения на один и тот же объект pictureImageView . Вам нужно сохранить массив pictureImageView и перебирать их так же, как вы делаете с изображениями, и назначить каждому изображению соответствующий вид изображения.

 for (int i=0; i < 10; i  )
{
    //It looks like myview is an ivar as well and should only be local
    myview = [[UIView alloc] init];
    myview.frame = CGRectMake(320*i , 0, 320, 300);
    [myview setBackgroundColor: [UIColor whiteColor]];


    UIImageView *tmp = [[UIImageView alloc] initWithFrame:CGRectMake(179, 11, 100, 100)];
    //NSMutableArray declared in header and already allocated
    [pictureImageViewArray addObject:tmp];
    tmp.tag = i;
    [myview addSubview: tmp];
    [tmp release];
    // Picture URL is accessed dynamically and loading correctly.
    [dataArray insertObject:[NSMutableArray arrayWithObjects:picUrl,[NSString stringWithFormat:@"%d", i],nil]       atIndex:i];

    [scrollView addSubview:myview];
    [myview release]; //<-- Fix memory leak
}

...

//inside of - (void) assignImageToImageView:
for(int i=0; i<[imgAndTagReference count] ;i  ){
     UIImage *img = [[imgAndTagReference objectAtIndex:i] objectAtIndex:0];
    [(UIImageView*)[pictureImageViewArray objectAtIndex:i] setImage:img];
}
  

Комментарии:

1. в цикле также происходит утечка экземпляров myview.

2. Да, это так! на самом деле я не смотрел на эту часть кода. Он выглядит как User… также неправильно использует ivars.

3. Спасибо. Я исправил эту проблему для (UIView * XView в [подразделах ScrollView]) { для (UIImageView * xyzView в [подвидах XView] ) { if ([тег xyzView] == [[imgAndTagReference objectAtIndex:1] intValue]) { // Найден просмотр изображения из тега, обновлен с помощью img [xyzView setImage:[imgAndTagReference objectAtIndex:0]]; } } }