如何使用多线程在UITableView中显示json图像数组?

时间:2012-04-20 05:34:13

标签: iphone xcode json uitableview

我的服务器上的图像很少,其名称存储在phpmysql表中。该表包含两个字段:id和images。我准备了一个php来获取json编码的图像,格式如下所述:

jsonFetch.php

<?php
$dbhost = "localhost";
$dbname = "userauth";
$dbuser = "root";
//$DB_Pass = "root";
$dbtable = "images";

@mysql_connect($dbhost, $dbuser);
$db = mysql_select_db($dbname);


$sql = "SELECT * FROM $dbtable";
$query = mysql_query($sql);

while($row = mysql_fetch_array($query))
    {
         $rows[] = array(
        //"id" => $row[0],
        "image" => $row[1]
        //"description" => $row['description']);
        );
    }

$json = json_encode($rows);
$callback = $_GET['images'];
echo $callback.$json ;   
//print_r($json);  

?>

现在,当我点击网址时,我得到了以下回复:

[{ “图像”:” ./ 95462 “},{” 图像 “:” ./ 8838upload_image.jpg “} {” 图像 “:” ./ 43185upload_image.jpg “},{” 图像 “:”/ 17426upload_image.jpg“}]

我正在上面获得json数组。

下一步是在UITableView中以多线程方式显示上面的数组。 当我对它们进行硬编码时,我从网址获取图像,但是当涉及到json解析时,我就是一个菜鸟。我已经尝试了解析json的所有方式,以便您参考,我发布.m文件。 :

#import "json.h"

@interface profilePhotos(Private)
- (void) initialize;
- (void) loadImage:(id)arg;
- (void) updateTableView:(id)arg;
- (void) addImagesToQueue:(NSArray *)images;
- (void) addImagesToQueue:(NSArray *)arrayImages;
- (void) addImagesToQueue:(NSArray *)arrayDataFromServer;
- (void) showcommentView;
- (void) hidecommentView;
@end

@implementation profilePhotos
@synthesize photosTable;
@synthesize addPhotos;
@synthesize deletePhotos;
@synthesize back;
@synthesize imageQueue, loadedImages, imageLoaderOpQueue, commentView;
//@synthesize photosView;


-(void)initializeWith:(int)buttonTag{

tag = buttonTag;

NSLog(@"tag = %d", tag);
 }

- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
 {
  if (!(self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
    return self;
  }

 [self initialize];
 return self;
  }

 - (void) awakeFromNib
 {
   NSLog(@"AsyncImageLoadingViewController::awakeFromNib called");
   [super awakeFromNib];
    [self initialize];
   }

 - (void) viewDidLoad
 {
NSLog(@"AsyncImageLoadingViewController::viewDidLoad called");
[super viewDidLoad];
 }

 - (void) viewDidAppear:(BOOL)animated
{
 NSLog(@"AsyncImageLoadingViewController::viewDidAppear called");
 [super viewDidAppear:animated];


 NSArray *images = [NSArray arrayWithObjects:
                   @"http://dl.dropbox.com/u/9234555/avatars/ava01.gif",
                   @"http://dl.dropbox.com/u/9234555/avatars/ava02.gif",
                   @"http://dl.dropbox.com/u/9234555/avatars/ava03.gif",
                   @"http://dl.dropbox.com/u/9234555/avatars/ava04.gif",
                   @"http://dl.dropbox.com/u/9234555/avatars/ava05.gif", nil];

[self addImagesToQueue:images];  
NSLog(@"addImagesToQueue: %@",self);


 }


 #pragma mark -
 #pragma mark Private Methods

  /*!
  @method     
  @abstract   initializes class variables
  */
 - (void) initialize
    {
      NSLog(@"AsyncImageLoadingViewController::initialize called");

      NSMutableArray *a = [[NSMutableArray alloc] init];
      self.imageQueue = a;
      //[a release];

      a = [[NSMutableArray alloc] init];
      self.loadedImages = a;
      //[a release];

      NSOperationQueue *queue = [[NSOperationQueue alloc] init];
      self.imageLoaderOpQueue = queue;
      //[queue release];
       }

        /*!
       @method     
       @abstract   updates tableview for the newly downloaded image and scrolls the          tableview to bottom
       */
     - (void) updateTableView:(id)arg
        {
         NSLog(@"AsyncImageLoadingViewController::updateTableView called");

         if ((arg == nil) || ([arg isKindOfClass:[UIImage class]] == NO)) {
            return;
    }

    // store the newly downloaded image
    [self.loadedImages addObject:arg];
    //[arg release];

    // refresh tableview
    [self.photosTable reloadData];

    // scroll to the last cell of the tableview
    NSIndexPath *lastRow = [NSIndexPath indexPathForRow:([self.loadedImages count] - 1) inSection:0];
    [self.photosTable scrollToRowAtIndexPath:lastRow
                            atScrollPosition:UITableViewScrollPositionBottom
                                    animated:YES];
}

 /*!
 @method     
 @abstract   downloads images, this is the method that dispatches tasks in the operation q ueue
 */
- (void) loadImage:(id)arg
 {
   NSLog(@"AsyncImageLoadingViewController::loadImage called");

   if ((arg == nil) || ([arg isKindOfClass:[NSString class]] == NO)) {
    return;
    }

    // create a local autorelease pool since this code runs not on main thread
    //NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    // fetch the image
    NSLog(@"AsyncImageLoadingViewController::loadImage - will download image: %@", arg);
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:arg]];
    UIImage *image = [UIImage imageWithData:data];
    NSLog(@"image: %@",image);

    // update tableview with the downloaded image on main thread
    [self performSelectorOnMainThread:@selector(updateTableView:) withObject:image    waitUntilDone:NO];

    //[pool release];
     }

  /*!
  @method     
  @abstract   adds images to the queue and starts the operation queue to download them
   */
 - (void) addImagesToQueue:(NSArray *)images
   {
    NSLog(@"AsyncImageLoadingViewController::addImagesToQueue called");

    [self.imageQueue addObjectsFromArray:images];
    NSLog(@"addImagesToQueue Array: %@", self);

    // suspend the operation queue
    [self.imageLoaderOpQueue setSuspended:YES];

    // add tasks to the operation queue
     for (NSString *imageUrl in self.imageQueue) {
     NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self                                              selector:@selector(loadImage:) object:imageUrl];
      [self.imageLoaderOpQueue addOperation:op];
      // [op release];
       }

// clear items in the queue and resume the operation queue to start downloading images
[self.imageQueue removeAllObjects];
[self.imageLoaderOpQueue setSuspended:NO];
    }


 #pragma mark -
 #pragma mark UITableViewDataSource Methods

  - (NSInteger)tableView:(UITableView *)tableView
  numberOfRowsInSection:(NSInteger)section
    {

return [self.loadedImages count];



       }

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

   static NSString *CellIdentifier = @"CellIdentifier";

cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{       
    //cell = [[[UITableViewCell alloc] initWithStyle:UITableViewStyleGrouped      reuseIdentifier:CellIdentifier] autorelease];
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewStyleGrouped   reuseIdentifier:[NSString stringWithFormat:@"cellID%d",indexPath.row]];

    cell.accessoryType =UITableViewCellAccessoryNone;
    //cell.accessoryType =UITableViewCellAccessoryDisclosureIndicator;




  }

for(UIView *subviews in cell.subviews)
    [subviews removeFromSuperview];


     UIImageView *photo;
     photo=[[UIImageView alloc] init];
     [photo setImage:[self.loadedImages objectAtIndex:indexPath.row]];
     [photo setFrame:CGRectMake(0, 5, 150, 120)];
     [cell addSubview:photo];  
     return cell;
       }





    -(void)aMethod:(UIButton *)sender{

//[sender tag];

NSIndexPath *indexPath = [photosTable indexPathForCell: (UITableViewCell*)[[sender superview]superview]];

NSLog(@"[sender tag] is %d",[sender tag]);



if([sender tag]==indexPath.row){

    textField = (UITextField*)[cell viewWithTag:[sender tag]];
    textField.hidden=NO;
    }
  //}


    }



#pragma mark -
#pragma mark UITableViewDelegate Methods

-(void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

[tableView deselectRowAtIndexPath:indexPath animated:YES];


}




 - (void)didReceiveMemoryWarning
   {
   // Releases the view if it doesn't have a superview.
   [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
     }

   - (void)viewDidUnload{
     // [self setPhotosView:nil];
  [self setPhotosTable:nil];
  [self setAddPhotos:nil];
  [self setDeletePhotos:nil];
  [self setBack:nil];
  [super viewDidUnload];
  // Release any retained subviews of the main view.
  // e.g. self.myOutlet = nil;
      }

   - (BOOL)shouldAutorotateToInterfaceOrientation:(  UIInterfaceOrientation)interfaceOrientation
      {
       // Return YES for supported orientations
      return (interfaceOrientation == UIInterfaceOrientationPortrait);
       }

我相信在viewDidAppear方法中需要做些什么,但是我不明白它是什么。

请帮助我。我已经尝试了所有可能的json方法。可能是我在做那些错误,但我一直很沮丧。请帮帮我。

3 个答案:

答案 0 :(得分:2)

Dude ..使用以下参考,您将获得教程作为工作演示..

images in UITableView using multithreading

See this reference if you are new in iOS. It's simple

希望,这会对你有帮助......

答案 1 :(得分:2)

我建议您使用SDWebImage

网络图片 该库为UIImageVIew提供了一个类别,支持来自Web的远程图像。

它提供:

UIImageView类别,将Web图像和缓存管理添加到Cocoa Touch框架 异步图像下载器 具有自动缓存到期处理的异步内存+磁盘映像缓存 保证不会多次下载相同的URL 保证不会一次又一次地重试伪造的URL 表演!

答案 2 :(得分:1)