iPhone-在NSURL连接完成之前,使UITableViewCells显示在视图加载上

iPhone-在NSURL连接完成之前,使UITableViewCells显示在视图加载上,iphone,uitableview,nsurlconnection,Iphone,Uitableview,Nsurlconnection,我正在尝试使用故事板和JSON创建一个松散版本的懒散图像。在主TableViewController上的ViewDidLoad中,我启动一个NSURLConnection以获取JSON数据,但我的单元格直到连接完成后才加载。我想要与LazyTableImages相同的行为,单元格加载为空白,但随后填充信息(重新加载表数据)。如果我不使用故事板,我可以复制它,因为LazyTables不使用故事板,但这不是一个选项 我浏览了一些懒散的图片,试图找到解决方案,但故事板(对我来说)起了很大的作用 有没有

我正在尝试使用故事板和JSON创建一个松散版本的懒散图像。在主TableViewController上的ViewDidLoad中,我启动一个NSURLConnection以获取JSON数据,但我的单元格直到连接完成后才加载。我想要与LazyTableImages相同的行为,单元格加载为空白,但随后填充信息(重新加载表数据)。如果我不使用故事板,我可以复制它,因为LazyTables不使用故事板,但这不是一个选项

我浏览了一些懒散的图片,试图找到解决方案,但故事板(对我来说)起了很大的作用

有没有一种简单的方法让电池作为空白加载?例如,如果设备没有internet,我仍然希望显示我的TableView,并且我将在单元格中放置一条自定义消息

代码:

viewDidLoad中初始化连接的部分

NSURLRequest *urlrequest = [NSURLRequest requestWithURL:[NSURL URLWithString:serverURL]];
    self.dataConnection = [[NSURLConnection alloc] initWithRequest:urlrequest delegate:self];

    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
连接正在加载

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    //ListData below is an array that my data received (JSON) is loaded into. It is then passed to getTableData.
    self.dataConnection = nil;
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self performSelectorOnMainThread:@selector(getTableData:) withObject:ListData waitUntilDone:YES];
    });
}
getTableData

-(void)getTableData:(NSData *)jsonData
{
    NSError *error = nil;
    arrayEntries = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableLeaves error:&error];
    for (int x = 0; x < arrayEntries.count; x++)
    {
        NSMutableDictionary *dic = [arrayEntries objectAtIndex:x];

        //ARecord is a class just like in LazyTableImages that creates objects to keep the icons/data together. The ARecords are loaded into the TableView
        ARecord *arecord = [[ARecord alloc] init];

        NSString *title = [dic objectForKey:@"title"];
        NSString *subt = [dic objectForKey:@"subtitle"];
        NSString *url = [dic objectForKey:@"image_URL"];
        arecord.Icon = nil;
        arecord.URL = url;
        arecord.Name = title;
        arecord.title = subt;

        //this is where I load an array full of the arecord objects.
        [array addObject:arecord];
    }
    [self.tableView reloadData];
}
-(void)getTableData:(NSData*)jsonData
{
n错误*错误=nil;
arrayEntries=[NSJSONSerialization JSONObjectWithData:jsonData选项:NSJSONReadingMutableLeaves错误:&error];
对于(int x=0;x
由于我没有看到您的代码,我只在这里给出我的建议:

- (void)viewDidLoad
{
    [super viewDidLoad];

    dispatch_queue_t queue = dispatch_queue_create(NULL, NULL);
    dispatch_async(queue, ^{

        //add your connection code here
        //parse the json and store the data
        //

        dispatch_async(dispatch_get_main_queue(), ^{

            //here to reload your table view again, 
            //since UI related method should run on main thread.

            [YOUR_TABLEVIEW reloadData];

        });

    });

    [YOUR_TABLEVIEW reloadData];
}

注意:确保序列图像板中的tableview已连接到代码中的tableview!希望有帮助

我用两个对象来实现这一点。首先,我有一个image fetcher类,它异步下载数据并在数据完成时通知委托。然后,我有一个图像视图类,它实现了fetcher的委托方法。比如:

@implementation AsyncImageFetcher
-(id)initWithURL:(NSURL *)aURL andDelegate:(id<SomeProtocol>)aDelegate{

  //...

  NSURLRequest *req = [NSURLRequest requestWithURL:aURL];
  //Note that NSURLConnection retains its delegate until the connection
  //terminates! See comments in MyImageView below.
  [NSURLConnection connectionWithRequest:req delegate:self];

  //...
}

//Implement standard connection delegates here. The important part is:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{

  // ...

  UIImage *anImage = [self decodeDownloadedDataIntoAnImage];
  if([[self delegate] respondsToSelector:@selector(imageFetcher:didFetchImage:)]){
    [[self delegate] imageFetcher:self didFetchImage:anImage];
  }

  //...
}

@end

在您的特定情况下,您只需在
-tableView:cellForRowAtIndexPath:
中将
MyImageView
设置为单元格的
imageView
,当然,为其占位符和URL传递合理的值。

我也做了类似的事情。在viewDidLoad中:我将表数据的数组设置为[NSNull null]的几个对象,以便在下载数据时显示多少空行。在cellForRowAtIndexPath中:我检查[self.ArrayFTableData objectAtIndex:indexPath.row]=[NSNull null]。如果是,则返回一个“空白”单元格,否则用ARRecrod数据加载单元格。
然后,当URL完成时,将NSNull数组替换为Arrescords数组。

您是否在主线程上调用了网络?如果是这样的话,网络会阻塞UI线程。我曾尝试使用GCD将其移出主线程,但随后我只得到一个白色屏幕,因为该表从未加载。NURLConnection中有一个GCD调用,用于处理不同线程上的JSON解析。请注意,您的NSURLConnection(应该)已经是异步的。将其移动到后台线程可能是个坏主意。正如奎因所说,就网络而言,“线程是邪恶的”™".我也记得这一点,但无论我如何剪切它;或者将NSURLConnection移动到后台线程,或者将解析移动到后台线程,直到NSURLConnection完成,单元格才会加载。我需要将初始下载移出UIs方式。您使用了asyn newworking,因此无需使用gcd。感谢您的帮助回答。我添加了代码以帮助消除任何混乱。只是花了一段时间才获得我需要的内容并正确编辑。我这样做很累,但我现在这样做是处理我的初始JSON调用的最佳方式。我在第二个类中获得图像,这只是为了获得包含URL的JSON的第一位,以获得图像稍后再同步。还有其他想法吗?谢谢,异步加载JSON也是一样。只是,不用
-decodingdowLoadedDataInAtanimage
,而是将下载的JSON数据解析为对象。不用图像作为委托,而是(大概)使用您的表的控制器,这样它就可以用新的JSON数据重新加载表了。谢谢。我一直认为这是我需要的方法,但我仍然无法让它工作。我添加了代码来帮助消除混乱。所以我尝试了这种方法,我只是挂断了调度调用。现在还有其他建议吗我没有发布一些代码吗?谢谢小心!在一个线程上进行网络连接几乎总是一个错误。工作非常完美,这正是我想要的。谢谢!
@implementation MyImageView

-(id)initWithURL:(NSURL *)aURL andPlaceHolderImage:(UIImage *)aPlaceHolder{

  //...

  [self setImage:aPlaceHolder];

  //Note we don't assign this to an ivar or retain it or anything. 
  //That's ok because the NSURLConnection inside the fetcher actually 
  //retains the fetcher itself. So it will live until the connection 
  //terminates -- which is exactly what we want. Thus we disable 
  //CLANG's noisy warnings.
  #pragma clang diagnostic push
  #pragma clang diagnostic ignored "-Wunused-value"
  [[AsyncImageFetcher alloc] initWithURL:aURL andDelegate:self];
  #pragma clang diagnostic pop

  return self;
}


-(void)imageFetcher:(MCMAsyncImageFetcher *)anImageFetcher didFetchImage:(UIImage *)anImage{
  [self setImage:anImage];
}

@end