UITableView cellForRowAtIndexPath阻止主线程

时间:2015-09-24 06:51:51

标签: ios objective-c multithreading uitableview

如标题中所述,

滚动tableview时会有一点延迟。

最奇怪的是,出列单元格占用了大部分的运行时间。

http://i.stack.imgur.com/qH8Lw.jpg

ShareTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

Share *share = [shares objectAtIndex:[indexPath row]];

[[cell profileImageView] sd_setImageWithURL:[NSURL URLWithString:[SERVER stringByAppendingString:[share profileImage]]] forState:UIControlStateNormal placeholderImage:[UIImage imageNamed:@"PlaceHolder"] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageUrl){
    dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), ^{
        UIImage *newImage;
        if ([image size].width > [image size].height){
            CGImageRef cropped = CGImageCreateWithImageInRect([image CGImage], CGRectMake([image size].width/2.0f-[image size].height/2.0f, 0, [image size].height, [image size].height));
            newImage = [UIImage imageWithCGImage:cropped scale:[image scale] orientation:[image imageOrientation]];
            CGImageRelease(cropped);
        } else if ([image size].width < [image size].height){
            CGImageRef cropped = CGImageCreateWithImageInRect([image CGImage], CGRectMake(0, [image size].height/2.0f-[image size].width/2.0f, [image size].width, [image size].width));
            newImage = [UIImage imageWithCGImage:cropped scale:[image scale] orientation:[image imageOrientation]];
            CGImageRelease(cropped);
        } else if (image == nil){
            newImage = [UIImage imageNamed@"PlaceHolder"];
        } else {
            newImage = image;
        }
        dispatch_async(dispatch_get_main_queue(), ^{
            [[cell profileImageView] setImage:newImage forState:UIControlStateNormal];
        });
    });
}];
[[cell usernameLabel] setTitle:[share userName] forState:UIControlStateNormal];
    //Date
{
    static NSDateFormatter *formatter;
    if (!formatter)
        formatter = [[NSDateFormatter alloc] init];
    if ([[share date] isToday]){
        [formatter setDateFormat:@"hh:mm a"];
        [[cell dateLabel] setText:[NSString stringWithFormat:@"Today, %@", [formatter stringFromDate:[share date]]]];
    } else if ([[share date] isYesterday]){
        [formatter setDateFormat:@"hh:mm a"];
        [cell.dateLabel setText:[NSString stringWithFormat:@"Yesterday, %@", [formatter stringFromDate:[share date]]]];
    } else {
        [formatter setDateFormat:@"MMM dd, YYYY"];
        [[cell dateLabel] setText:[formatter stringFromDate:[share date]]];
    }
}

[[cell titleLabel] setText:[share title]];
if (![[share hashtag] isEqualToString:@""])
    [[cell tagLabel] setText:[NSString stringWithFormat:@"#%@", [share hashtag]]];
else
    [[cell tagLabel] setText:@""];

[[cell contentsLabel] setText:nil];
[[cell contentsLabel] setText:[NSString stringWithFormat:@"\u200B%@", [share comment]]];
[[cell contentsLabel] setDataDetectorTypes:UIDataDetectorTypeLink];

[[[cell scrollView] subviews]
   makeObjectsPerformSelector:@selector(removeFromSuperview)];
if ([[share photos] count] != 0){
    CGFloat x = 0;
    CGRect bound = [[UIScreen mainScreen] bounds];
    for (NSString *photo in [share photos]){
        UIButton *imageButton = [UIButton buttonWithType:UIButtonTypeCustom];
        [imageButton setFrame:CGRectMake(x, 0, bound.size.width-20.0f, (bound.size.width-20.0f)*3.0f/4.0f)];
        [SDWebImageDownloader.sharedDownloader downloadImageWithURL:[NSURL URLWithString:[SERVER stringByAppendingString:photo]]
            options:0
            progress:^(NSInteger receivedSize, NSInteger expectedSize)
            {
                 // progression tracking code
            }
            completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished)
            {
               if (image && finished)
               {
                   dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), ^{
                       CGRect bound = [[UIScreen mainScreen] bounds];
                       CGSize newSize = CGSizeMake(bound.size.width-20.0f, (bound.size.width-20.0f)*3.0f/4.0f);
                       UIImage *newImage;
                       if ([image size].height > [image size].width/4.0f*3.0f){
                           CGImageRef cropped = CGImageCreateWithImageInRect([image CGImage], CGRectMake(0, image.size.height/2.0f-([image size].width/4.0f*3.0f)/2.0f, [image size].width, [image size].width/4.0f*3.0f));
                           UIImage *old = [UIImage imageWithCGImage:cropped scale:[image scale] orientation:[image imageOrientation]];
                           CGImageRelease(cropped);

                           UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
                           [old drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
                           newImage = UIGraphicsGetImageFromCurrentImageContext();
                           UIGraphicsEndImageContext();
                       } else if ([image size].height/3.0f*4.0f < [image size].width){
                           CGImageRef cropped = CGImageCreateWithImageInRect([image CGImage], CGRectMake(image.size.width/2.0f-([image size].height/3.0f*4.0f)/2.0f, 0, [image size].height/3.0f*4.0f, [image size].height));
                           UIImage *old = [UIImage imageWithCGImage:cropped scale:[image scale] orientation:[image imageOrientation]];
                           CGImageRelease(cropped);

                           UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
                           [old drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
                           newImage = UIGraphicsGetImageFromCurrentImageContext();
                           UIGraphicsEndImageContext();
                       } else {
                           UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
                           [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
                           newImage = UIGraphicsGetImageFromCurrentImageContext();
                           UIGraphicsEndImageContext();
                       }
                       dispatch_async(dispatch_get_main_queue(), ^{
                           [imageButton setImage:newImage forState:UIControlStateNormal];
                       });
                   });
                }
        }];

        [imageButton setTag:[indexPath row]];
        [imageButton addTarget:self action:@selector(showImage:) forControlEvents:UIControlEventTouchUpInside];
        [[cell scrollView] addSubview:imageButton];
        x += bound.size.width-20.0f;
    }
    [[cell scrollView] setContentSize:CGSizeMake(x, (bound.size.width-20.0f)/4.0f*3.0f)];
    if (x > bound.size.width-20.0f) {
        [[cell scrollView] setContentOffset:CGPointMake(10.0f, 0.0f)];
    }
}

if ([share userLikedPost])
    [[cell likeButton] setSelected:YES];
else
    [[cell likeButton] setSelected:NO];
if ([share likeCount] == 0)
    [[cell likedButton] setTitle:@"Liked" forState:UIControlStateNormal];
else
    [[cell likedButton] setTitle:[NSString stringWithFormat:@"%d", [share likeCount]] forState:UIControlStateNormal];
if ([share reviewCount] == 0)
    [[cell answerButton] setTitle:@"Comments" forState:UIControlStateNormal];
else
    [[cell answerButton] setTitle:[NSString stringWithFormat:@"%d", [share reviewCount]] forState:UIControlStateNormal];

//Setup Targets
{
    if ([[[cell usernameLabel] allTargets] count] == 0)
        [[cell usernameLabel] addTarget:self action:@selector(showUserShares:) forControlEvents:UIControlEventTouchUpInside];
    if ([[[cell profileImageView] allTargets] count] == 0)
        [[cell profileImageView] addTarget:self action:@selector(showUserShares:) forControlEvents:UIControlEventTouchUpInside];
    if ([[[cell likeButton] allTargets] count] == 0)
        [[cell likeButton] addTarget:self action:@selector(likePressed:) forControlEvents:UIControlEventTouchUpInside];
    if ([[[cell likedButton] allTargets] count] == 0)
        [[cell likedButton] addTarget:self action:@selector(showWhoLiked:) forControlEvents:UIControlEventTouchUpInside];
    if ([[[cell answerButton] allTargets] count] == 0)
        [[cell answerButton] addTarget:self action:@selector(reviewPressed:) forControlEvents:UIControlEventTouchUpInside];
    if ([[[cell moreButton] allTargets] count] == 0)
        [[cell moreButton] addTarget:self action:@selector(morePressed:) forControlEvents:UIControlEventTouchUpInside];
}

[cell setTag:indexPath.row];

return cell;

我有什么遗失的吗?

0 个答案:

没有答案