在后台线程中解析JSON图像(AFNetworking)

时间:2013-11-11 16:13:35

标签: ios json afnetworking

我有一个图像幻灯片,其中包含使用JSON解析的图像,我想在后台线程中运行该幻灯片。

我的原始代码:

- (void)loadVisiblePages {
    // First, determine which page is currently visible
    CGFloat pageWidth = self.scrollView.frame.size.width;
    NSInteger page = (NSInteger)floor((self.scrollView.contentOffset.x * 2.0f + pageWidth) / (pageWidth * 2.0f));

    // Update the page control
    self.pageControl.currentPage = page;

    // Work out which pages we want to load
    NSInteger firstPage = page - 1;
    NSInteger lastPage = page + 1;

    // Purge anything before the first page
    for (NSInteger i=0; i<firstPage; i++) {
        [self purgePage:i];
    }
    for (NSInteger i=firstPage; i<=lastPage; i++) {
        [self loadPage:i];
    }
    for (NSInteger i=lastPage+1; i<self.pageImages.count; i++) {
        [self purgePage:i];
    }
}

- (void)loadPage:(NSInteger)page {
    if (page < 0 || page >= self.pageImages.count) {
        // If it's outside the range of what we have to display, then do nothing
        return;
    }

    // Load an individual page, first seeing if we've already loaded it
    UIView *pageView = [self.pageViews objectAtIndex:page];
    if ((NSNull*)pageView == [NSNull null]) {
        CGRect frame = self.scrollView.bounds;
        frame.origin.x = frame.size.width * page;
        frame.origin.y = 0.0f;

        UIImageView *newPageView = [[UIImageView alloc] initWithImage:[self.pageImages objectAtIndex:page]];
        newPageView.contentMode = UIViewContentModeScaleAspectFit;
        newPageView.frame = frame;
        [self.scrollView addSubview:newPageView];
        [self.pageViews replaceObjectAtIndex:page withObject:newPageView];
    }
}

- (void)purgePage:(NSInteger)page {
    if (page < 0 || page >= self.pageImages.count) {
        // If it's outside the range of what we have to display, then do nothing
        return;
    }

    // Remove a page from the scroll view and reset the container array
    UIView *pageView = [self.pageViews objectAtIndex:page];
    if ((NSNull*)pageView != [NSNull null]) {
        [pageView removeFromSuperview];
        [self.pageViews replaceObjectAtIndex:page withObject:[NSNull null]];
    }
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSArray *images = _singleRelease[@"images"];
    NSMutableArray *mediumImages = [NSMutableArray array];

    for (NSDictionary *imageDictionary in images){
        NSURL *imageURL = [NSURL URLWithString:imageDictionary[@"image_file"][@"image_file"][@"medium"][@"url"]];

        NSData *imageData = [NSData dataWithContentsOfURL:imageURL];

        UIImage *image = [UIImage imageWithData:imageData];
        [mediumImages addObject:image];
    }

    self.pageImages = [mediumImages copy];

    NSInteger pageCount = self.pageImages.count;

    self.pageControl.currentPage = 0;
    self.pageControl.numberOfPages = pageCount;

    self.pageViews = [[NSMutableArray alloc] init];
    for (NSInteger i = 0; i < pageCount; ++i) {
        [self.pageViews addObject:[NSNull null]];
    }
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    // 4
    CGSize pagesScrollViewSize = self.scrollView.frame.size;
    self.scrollView.contentSize = CGSizeMake(pagesScrollViewSize.width * self.pageImages.count, pagesScrollViewSize.height);

    // 5
    [self loadVisiblePages];
}

#pragma mark - UIScrollViewDelegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    // Load the pages which are now on screen
    [self loadVisiblePages];
}

我尝试自定义我在网上找到的代码示例,但我无法使用我的代码。

这是我到目前为止所做的:

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSArray *images = _singleRelease[@"images"];
    NSMutableArray *mediumImages = [NSMutableArray array];

    dispatch_queue_t imageQueue = dispatch_queue_create("Image Queue",NULL);

    for (NSDictionary *imageDictionary in images){
        dispatch_async(imageQueue, ^{

            NSURL *imageURL = [NSURL URLWithString:imageDictionary[@"image_file"][@"image_file"][@"medium"][@"url"]];
            NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
            UIImage *image = [UIImage imageWithData:imageData];
            [mediumImages addObject:image];

            dispatch_async(dispatch_get_main_queue(), ^{


                NSInteger pageCount = self.pageImages.count;

                self.pageImages = [mediumImages copy];

                self.pageControl.currentPage = 0;
                self.pageControl.numberOfPages = pageCount;

                self.pageViews = [[NSMutableArray alloc] init];
                for (NSInteger i = 0; i < pageCount; ++i) {
                    [self.pageViews addObject:[NSNull null]];
                }
            });

        });
    }
}

这是我尝试自定义的另一个代码示例,但我得到了相同的结果。

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSArray *images = [self.singleRelease[@"images"] copy];

    __weak __typeof__(self) weakself = self;

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSMutableArray *mediumImages = [NSMutableArray array];

        for (NSDictionary *imageDictionary in images){
            NSURL *imageURL = [NSURL URLWithString:imageDictionary[@"image_file"][@"image_file"][@"medium"][@"url"]];
            NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
            UIImage *image = [UIImage imageWithData:imageData];

            if (image) {
                [mediumImages addObject:image];
            }
        }

        dispatch_sync(dispatch_get_main_queue(), ^{

            if (weakself) {
                __typeof__(self) weakself = weakself;
                self.pageImages = mediumImages;
                NSInteger pageCount = self.pageImages.count;
                self.pageControl.currentPage = 0;
                self.pageControl.numberOfPages = pageCount;

                self.pageViews = [[NSMutableArray alloc] init];
                for (NSInteger i = 0; i < pageCount; ++i) {
                    [self.pageViews addObject:[NSNull null]];
                }

            };
        });
    });
}

两个代码都会使用正确数量的幻灯片加载我的页面控件,但图像不会显示。

有任何帮助吗?感谢。

1 个答案:

答案 0 :(得分:0)

修正了它。

删除viewWillAppear,然后将当前viewDidLoad替换为:

/**
 *  Called after the controller’s view is loaded into memory.
 */
- (void)viewDidLoad
{
    [super viewDidLoad];

    self.release_name.text              = [self.singleRelease objectForKey:@"release_name"];

    if ([_singleRelease objectForKey:@"release_price"])
        self.release_price.text         = [NSString stringWithFormat:@"$%@",[_singleRelease objectForKey:@"release_price"]];

    self.release_colorway.text          = [self.singleRelease objectForKey:@"release_colorway"];

    if([_singleRelease objectForKey:@"release_date"] != NULL)
    {
        NSString *readableDate          = [_singleRelease objectForKey:@"release_date"]; // I assume that this is a string
        UpcomingRelease *upcoming       = [[UpcomingRelease alloc] init];
        upcoming.release_date           = readableDate;

        self.release_date.text          = [NSString stringWithFormat:@"%@", upcoming.formattedDate];
    }

    NSArray *images                     = self.singleRelease[@"images"];

    //  we get the image on a background queue
    dispatch_queue_t imageQueue         = dispatch_queue_create("Image Queue",NULL);
    dispatch_async(imageQueue,
    ^{
        NSMutableArray *mediumImages    = [[NSMutableArray alloc] initWithCapacity:images.count];
        //  for each image url we get the image and add it to the array
        for (NSDictionary *imageDictionary in images)
        {
            NSURL *imageURL             = [[NSURL alloc] initWithString:imageDictionary[@"image_file"][@"image_file"][@"medium"][@"url"]];
            NSData *imageData           = [[NSData alloc] initWithContentsOfURL:imageURL];
            UIImage *image              = [[UIImage alloc] initWithData:imageData];
            [mediumImages addObject:image];
        }

        //  once we have obtained all of the images we use them
        dispatch_async(dispatch_get_main_queue(),
        ^{
            //  we get a strong pointer to the images array and set the pages count according to how many there are
            self.pageImages             = [mediumImages copy];
            NSInteger pageCount         = self.pageImages.count;

            //  we set the page control appropriate for the number of images that need to be presented
            self.pageControl.currentPage    = 0;
            self.pageControl.numberOfPages  = pageCount;

            //  we then make mock page views
            self.pageViews              = [[NSMutableArray alloc] init];
            for (NSInteger i = 0; i < pageCount; ++i)
            {
                [self.pageViews addObject:[NSNull null]];
            }

            //  once we have the images we load the pages with them
            CGSize pagesScrollViewSize  = self.scrollView.frame.size;
            self.scrollView.contentSize = CGSizeMake(pagesScrollViewSize.width * self.pageImages.count, pagesScrollViewSize.height);
            [self loadVisiblePages];
        });
    });
    _scrollView.showsHorizontalScrollIndicator=NO;
    _scrollView.showsVerticalScrollIndicator=NO;
}

问题是你试图在图像完成提取之前加载页面。