2010-10-26 2 views
0

J'ai publié mon application et j'ai remarqué le caractère saccadé lors du défilement dans le CellForRowAtIndexPath, parce que je suis en train de rendre une image à partir d'un flux JSON via une URL. J'ai cherché sur Internet et trouvé quelques exemples et celui-ci j'ai presque travaillé. Le problème est quand il rend les images ne correspondent pas au titre correct. Quelqu'un peut-il jeter un coup d'oeil et voir si je fais quelque chose qui ne va pas?Iphone cellForRowAtIndexPath Jerky lors du défilement asynchrone problème

Anyway ici mon code:

- (void)displayImage:(UIImage *)image { 
[photo setImage:image]; 

}

-(void)loadImage:(NSString *)url { 
NSData* imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]]; 
UIImage* image = [[[UIImage alloc] initWithData:imageData] autorelease]; 
[imageData release]; 
[self performSelectorOnMainThread:@selector(displayImage:) withObject:image waitUntilDone:NO]; 

}

cellForRowAtIndexPath methord

#define DATELABEL_TAG 1 #define MAINLABEL_TAG 2 #define PHOTO_TAG 3 UIImageView *photo; 



- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 




static NSString *MainNewsCellIdentifier = @"MainNewsCellIdentifier"; 

UILabel *mainLabel, *dateLabel; 


UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: MainNewsCellIdentifier]; 

if (cell == nil) 
{ 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier: MainNewsCellIdentifier] autorelease]; 
    cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; 

    dateLabel = [[[UILabel alloc] initWithFrame:CGRectMake(15.0,15.0,170.0,15.0)] autorelease]; 
    dateLabel.tag = DATELABEL_TAG; 
    dateLabel.font = [UIFont systemFontOfSize:10.0]; 
    dateLabel.textAlignment = UITextAlignmentLeft; 
    dateLabel.textColor = [UIColor darkGrayColor]; 
    dateLabel.autoresizingMask = UIViewAutoresizingFlexibleRightMargin; 
    [cell.contentView addSubview:dateLabel];  

    mainLabel = [[[UILabel alloc] initWithFrame:CGRectMake(15.0,28.0,170.0,60.0)] autorelease]; 
    mainLabel.tag = MAINLABEL_TAG; 
    mainLabel.font = [UIFont boldSystemFontOfSize:14.0]; 
    mainLabel.textColor = [UIColor blackColor]; 
    mainLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin; 
    mainLabel.numberOfLines = 0; 
    [cell.contentView addSubview:mainLabel]; 


    photo = [[[UIImageView alloc] initWithFrame:CGRectMake(190.0,15.0,85.0,85.0)] autorelease]; 
    photo.tag = PHOTO_TAG;  
    photo.contentMode = UIViewContentModeScaleAspectFit; 

    [cell.contentView addSubview:photo]; 
} 
else { 

    dateLabel = (UILabel *)[cell.contentView viewWithTag:DATELABEL_TAG]; 
    mainLabel = (UILabel *)[cell.contentView viewWithTag:MAINLABEL_TAG]; 
    photo = (UIImageView *)[cell.contentView viewWithTag:PHOTO_TAG]; 
} 

NSUInteger row = [indexPath row]; 
NSDictionary *stream = (NSDictionary *) [dataList objectAtIndex:row]; 
NSString *title = [stream valueForKey:@"title"]; 


NSString *titleString = @""; 

if(! [title isKindOfClass:[NSString class]]) 
{ 
    titleString = @""; 
} 
else 
{ 
    titleString = title; 
} 

CGSize maximumSize = CGSizeMake(180, 9999); 

UIFont *dateFont = [UIFont fontWithName:@"Helvetica" size:14]; 
CGSize dateStringSize = [titleString sizeWithFont:dateFont 
           constrainedToSize:maximumSize 
            lineBreakMode:mainLabel.lineBreakMode]; 

CGRect dateFrame = CGRectMake(15.0, 28.0, 170.0, dateStringSize.height); 
mainLabel.frame = dateFrame; 

mainLabel.text = titleString; 
dateLabel.text = [stream valueForKey:@"created"]; 

NSString *i = [NSString stringWithFormat:@"http://www.domain.co.uk/images/stories/%@", [stream valueForKey:@"image"]]; 


photo.image = [UIImage imageNamed:@"i_digital_media.png"]; 
NSOperationQueue *queue = [NSOperationQueue new]; 
NSInvocationOperation *operation = [[NSInvocationOperation alloc] 
            initWithTarget:self 
            selector:@selector(loadImage:) 
            object:i]; 
[queue addOperation:operation]; 
[operation release]; 


return cell;} 
+0

Il y a beaucoup de code là, et beaucoup de problèmes, pourquoi est-photo une variable statique? –

+0

Donc, il peut être vu dans le methode 'displayImage', ce n'est pas la bonne façon de faire? tous les conseils aideraient. – Robert

Répondre

0

Au moment où votre image est chargée, la photo variable i s a une autre photo :)

Vous devez passer à la fois l'image chargée et la UIImageView que vous souhaitez mettre à jour en arrière - essayez d'utiliser un NSDictionary pour passer des variables entre les fils:

- (void)displayImage:(NSDictionary *)info { 
    [[info objectForKey:@"photo"] setImage:[info objectForKey:@"image"]]; 
} 


-(void)loadImage:(NSDictionary *)info { 
    NSString *imagePath = [info objectForKey:@"imagePath"]; 
    UIImageView *photo = [info objectForKey:@"photo"]; 

    // Load the image 
    NSData* imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]]; 
    UIImage* image = [[[UIImage alloc] initWithData:imageData] autorelease]; 
    [imageData release]; 

    // Pass it back to the main thread 
    NSDictionary *mainThreadInfo = [NSdictionary dictionaryWithObjectAndKeys:image, @"image", photo, @"photo", nil]; 
    [self performSelectorOnMainThread:@selector(displayImage:) withObject:mainThreadInfo waitUntilDone:YES]; 
} 

maintenant , votre opération transmettra la photo et les données d'image au thread principal. Créer l'opération comme ceci:

NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:i, @"imagePath", photo, @"photo", nil]; 
NSInvocationOperation *operation = [[NSInvocationOperation alloc] 
            initWithTarget:self 
            selector:@selector(loadImage:) 
            object:info]; 

Et se débarrasser de la variable photo globale :)

+0

TOP Top top man – Robert

+0

Je vais nommer mon deuxième enfant Dean. – Robert

+0

Des conseils sur le reste de mon code en cas de fuite de mémoire? – Robert

Questions connexes