【问题标题】:How to display json image array in UITableView using multithreading?如何使用多线程在 UITableView 中显示 json 图像数组?
【发布时间】:2012-05-01 17:14:53
【问题描述】:

我的服务器上的图像很少,其名称存储在 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);  

?>

现在,当我点击 url 时,我得到以下响应:

[{"image":"./95462"},{"image":"./8838upload_image.jpg"}{"image":"./43185upload_image.jpg"},{"image":"/ 17426upload_image.jpg"}]

我得到如上的 json 数组。

接下来就是在UITableView中以多线程的方式显示上面的数组。 当我对它们进行硬编码时,我从 url 获取图像,但是当涉及到 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 方法。可能是我在这方面犯了一些错误,但我一直很沮丧。请帮帮我。

【问题讨论】:

  • 如果有人能够弄清楚上述代码,请告诉我

标签: iphone xcode json uitableview


【解决方案1】:

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

images in UITableView using multithreading

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

希望对你有所帮助...

【讨论】:

  • thanx a ton for the example 因为这几乎正是我想要的,但我面临着某些问题,即我应该在上面发布的代码中的何处使用此示例,或者我应该在示例中的何处进行更改本身以我的方式工作。我是 iOS 上的新手 [2 周经验] 并试图在需要知道的基础上接受培训...请帮助我,,,,
  • @LokeshBhatija : 对于新手说谎,这不是一件容易的事。所以,我建议你阅读机器人文章并阅读它。我还添加了新的参考。
  • 旧的 markofjohnson 程序。我经历过这个。 HJCache 导致错误。我会尽快发布这些错误。同时,我将研究您提到的先前参考文献
  • 我试过see this reference if you are new in iOS,但我不能实现同样的,原因是我上面写的php脚本没有获取数据。我试图操纵 php,但是每当我热 url 时,我都会得到 json 响应,但是当我在 Xcode 中尝试时,我得到的响应为 NULL。
  • touch-code-magazine.com/tutorial-fetch-and-parse-json 使用这个 url 它展示了如何从 url 加载数据..享受..
【解决方案2】:

我建议你使用SDWebImage

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

它提供:

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

【讨论】:

  • 你能给我提供一些使用 sdwebview 在同一行上的例子吗?
【解决方案3】:

【讨论】:

  • 你能帮我举出类似于link的活生生的例子吗?我需要同样的东西,但不同的是我需要来自 localhost 服务器而不是网页的图像数组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-20
相关资源
最近更新 更多