Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/98.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 重新加载RowsatindExpaths是否停止加载UITableViewCells?_Objective C_Ios_Tableview - Fatal编程技术网

Objective c 重新加载RowsatindExpaths是否停止加载UITableViewCells?

Objective c 重新加载RowsatindExpaths是否停止加载UITableViewCells?,objective-c,ios,tableview,Objective C,Ios,Tableview,我正在尝试将favicons合并到一个UITableView中。这个表基本上是用来访问网站的,我想在右边显示favicon。我最初在右边放了一个占位符图标,让一个函数在后台运行。此函数获取网站的URL,对其进行解析并尝试查找favicon。如果找不到,则保留相同的占位符图像;否则,它将用站点的favicon替换它。我最初尝试使用[tableView reloadData],它在模拟器中工作得很好,但它确实做了一些奇怪和不可靠的事情(例如,它会创建一些单元格,但随后会留下一个巨大的空白单元格)。无

我正在尝试将favicons合并到一个UITableView中。这个表基本上是用来访问网站的,我想在右边显示favicon。我最初在右边放了一个占位符图标,让一个函数在后台运行。此函数获取网站的URL,对其进行解析并尝试查找favicon。如果找不到,则保留相同的占位符图像;否则,它将用站点的favicon替换它。我最初尝试使用[tableView reloadData],它在模拟器中工作得很好,但它确实做了一些奇怪和不可靠的事情(例如,它会创建一些单元格,但随后会留下一个巨大的空白单元格)。无论如何,我偶然发现了重载rowsatindexpaths,这似乎是我需要使用的函数。然而,结果仍然相当不可靠。我的抓取功能在后台运行,如下所示:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...//other code here for showing website labels

    //obtain the favicon.ico
if(!this_article.iconLoaded){
    this_article.iconLoaded = TRUE;
    NSDictionary *args = [NSDictionary dictionaryWithObjectsAndKeys:this_article, @"article", indexPath, @"indexPath", nil];
    [self performSelectorInBackground:@selector(fetchFaviconWrapper:) withObject:args];
}

cell.favicon.image = this_article.icon;

return cell;
}
在FetchFaviconWrapper中:

- (void)fetchFaviconWrapper:(NSDictionary *)args {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[self fetchFavicon:[args objectForKey:@"article"]];
NSArray *paths = [NSArray arrayWithObject:[args objectForKey:@"indexPath"]];
[articleTable beginUpdates];
[articleTable reloadRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationFade];
[articleTable endUpdates];
[pool release];
}

基本上,fetchFavicon获取一个网站,获取主机URL,附加“/favicon.ico”,将其构造成一个NSData对象,并查找图像(如果存在)。然而,这也相当不可靠。在后台运行线程时,替换占位符图像的最佳方法是什么?我可以在主线程上做任何事情,但这只会使表加载缓慢。似乎有些东西我忽略了,或者是我忘了加上了……就是想不出来。

我有几点建议

  • 追加./favicon.ico并不总是准确的。研究向站点添加favicon以支持它们的各种方法

  • 至于替换默认占位符,我建议使用
    NSNotificationCenter
    通知主线程何时进行更改


  • 还不完全清楚您是否从单独的线程访问和修改UI

    如果是这样,这就是你不可靠的原因。UIKit只能从主线程访问。如果你感兴趣,你会发现很多关于S.O.的问题,还有很多关于网络的讨论

    如果您想保留第二个线程,有一个变通方法。实际上,您可以使用以下方式向UI对象发送消息:

    -performSelectorOnMainThread:withObject:waitUntilDone:
    
    而不是直接从辅助线程发送它们


    如果这个解决方法不能解决您的问题,那么我建议重新设计您的应用程序,使辅助线程只访问您的模型,而不访问UI。所有修改UI的操作都应该在主线程上执行。如果您需要在模型准备就绪时调用表上的
    reloadData
    ,您可以使用
    performSelectorOnMainThread:withObject:waitUntilDone
    ,我明确重申没有来自后台线程的UI

    更改初始代码:

    - (void)fetchFaviconWrapper:(NSDictionary *)args {
      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
      [self fetchFavicon:[args objectForKey:@"article"]];
      NSArray *paths = [NSArray arrayWithObject:[args objectForKey:@"indexPath"]];
    
      [articleTable beginUpdates];
      [articleTable reloadRowsAtIndexPaths:paths 
                          withRowAnimation:UITableViewRowAnimationFade];
      [articleTable endUpdates];
    
      [pool release];
    }
    
    看看你是否还有问题

    - (void)fetchFaviconWrapper:(NSDictionary *)args {
      NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
      [self fetchFavicon:[args objectForKey:@"article"]];
      NSArray *paths = [NSArray arrayWithObject:[args objectForKey:@"indexPath"]];
    
      [self performSelectorOnMainThread:@selector(reloadData) 
                             withObject:nil 
                          waitUntilDone:YES];
    
      [pool release];
    }
    
    在这种情况下,waitUntilDone是不相关的,最好是说YES


    当您有时髦的单元行为时,另一个值得怀疑的问题是您是否正确地处理了单元重用。你没有给我们看那个密码,所以我们说不出来。如果您在某处保留对某个单元格的引用,并将图像数据设置到该单元格中,那么当表从您下面重用该单元格时,您将使用软管。(我不认为这是本案的问题。)

    是的,我试过了,但基本上得到了相同的结果。不过,我确实注意到,如果我向下滚动,最初没有显示的网站(如前5-6个)会在我向下滚动时重新加载。所以,我想这只是前6个有问题的人。但为什么会有这种行为呢?此外,我意识到,当按下时,重新加载正确动画的单元格(高亮显示时变为蓝色)和未正确动画的单元格。只是一个问题:您是否正在从辅助线程修改UI(使用UIKit)?嗯,我设置了什么(如果我回忆正确的话)我的网站是通过performSelectorInBackground获取的。在fetcher函数的末尾,我有
    [articleTable reloadData]
    。我不知道这是否会把事情搞砸,但我想所有这些都是在后台的一个单独线程上运行的。当调用
    cellforrowatinexpath
    时,当需要确定要显示哪个favicon时,它会启动一个额外的线程(如原文章中所述)。请参阅我的编辑。我认为您可以通过
    -performselectornmainthread
    发送
    重新加载数据。让我再说一次(很抱歉这么迂腐):UIKit不是从辅助线程使用的。我建议您做一个简单的测试:删除
    [self-performSelectorInBackground:@selector(fetchFaviconWrapper:)with-Object:args]并在同一(主)线程中调用
    fetchFaviconWrapper
    。它会很慢,但我想它会工作得很好;我只是省略了大部分细节,因为它不太相关。