【问题标题】:App crashes when going back from view controller with tableview使用 tableview 从视图控制器返回时应用程序崩溃
【发布时间】:2013-06-04 00:17:10
【问题描述】:

我有一个带有初始图像的表格视图的视图控制器。 我正在使用 AFNetworking 加载图像,有时(主要是在我的互联网连接速度较慢时)当我单击视图控制器中的后退按钮项并进入 rootviewcontroller 时,应用程序崩溃并且我收到以下消息:

-[__NSCFDictionary numberOfSectionsInTableView:]: unrecognized selector sent to instance 0x1f567e30

为什么? 我正在使用 ARC。 这是我加载图片的代码

if(item.thumb)
    {
        [cell.listItemImage setImage: item.thumb];

    }
    else
    {

        UIActivityIndicatorView *loadingSymbol = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleGray];
        loadingSymbol.frame = CGRectMake(0, 0, cell.listItemImage.frame.size.width, cell.listItemImage.frame.size.height);
        [cell.listItemImage addSubview: loadingSymbol];
        [loadingSymbol startAnimating];


        [cell.listItemImage setImageWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString: item.thumbUrl]]
                                  placeholderImage:[UIImage imageNamed:@"transparent.png"]
                                           success:^(NSURLRequest *request , NSHTTPURLResponse *response , UIImage *image )
        {

                item.thumb = image;
            [cell setNeedsLayout];
                [loadingSymbol removeFromSuperview];
               [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];

        }
        failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error)
        {
             NSLog(@"something went wrong wiv the images");
            NSLog(@"%@", error);
             //[loadingSymbol removeFromSuperview];

        }
         ];
    }
}

如果有人可以在这里帮助我,我会很高兴!

编辑:

解决了我的第一个问题。但是现在,当我在表格视图中滚动时,应用程序崩溃了。我认为这与以下行有关:

[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];

任何想法为什么?

【问题讨论】:

  • 根据错误消息,您设法将 NSDictionaryObject 分配给框架需要表委托的某些属性。
  • 所以当表格视图控制器已经发布但后台仍有数据加载时会发生这种情况。显然,您保留了对不应再存在的单元格对象的引用。单元本身可能仍然存在,因为 ARC 取决于这是强引用还是弱引用。
  • 我不确定。 '[cell setNeedsLayout]' 是否会导致在表格或其控制器不再存在时重绘单元格和表格?但是,您应该找到一些更聪明的解决方案。要么在返回时取消所有打开的请求,要么在相关视图不再可见/不存在时不处理数据。
  • 嗯,我回去后如何取消打开的请求?
  • 你没有使用UIImageView+AFNetworking吗?

标签: ios objective-c tableview afnetworking


【解决方案1】:

在视图控制器的dealloc 方法中添加以下行。这在一个项目中对我有用。

[[UIImageView af_sharedImageRequestOperationQueue] cancelAllOperations];  

您的 dealloc 将如下所示

-(void)dealloc
{
  [[UIImageView af_sharedImageRequestOperationQueue] cancelAllOperations];  

  //your other clean ups

  [super dealloc];
}

编辑

在ViewController的头文件中,为UITableView添加一个IBOutlet

IBOutlet UITableView *myTableView;

从 Interface Builder 将您的 UITableView 连接到该插座 (myTableView)。

在你的 dealloc 中将 IBOutlet 设置为 nil

-(void)dealloc
{
   myTableView = nil;
   //your other clean ups
   [super dealloc];
}

你的成功块应该是这样的

success:^(NSURLRequest *request , NSHTTPURLResponse *response , UIImage *image )
        {
           if(myTableView)
           {
              item.thumb = image;
              [cell setNeedsLayout];
              [loadingSymbol removeFromSuperview];
             [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
           }

        }

编辑 2(滚动)

在您的成功块中,而不是:

[tableView reloadRowsAtIndexPaths:[NSArray arayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];

用途:

[tableView reloadRowsAtIndexPaths:[tableView indexPathsForVisibleRows] withRowAnimation:UITableViewRowAnimationNone];

【讨论】:

  • 谢谢,但是当我按照您所说的进行操作时出现以下错误:no known class method for selector af_sharedImageRequestOperationQueue ?
  • 您是否将#import "UIImageView+AFNetworking.h" 放入您的视图控制器文件中? (包括 .h 文件)
  • 这很奇怪,因为库的最新版本有那个方法.. .(参考源代码...)我要编辑答案并添加另一个解决方法
  • (不要将列表格式与源格式混用。这样会搞砸的。)
  • 嗯等等,现在滚动tableview时它崩溃了??
【解决方案2】:

问题:网络 I/O 在您的视图控制器释放后的一段时间内完成。由于网络 I/O,您重新加载了一些单元。重新加载单元格会调用视图控制器(已释放)以获取数据源信息和崩溃。

解决方案:必须在 dealloc 中将 table view delegate 和 dataSource 清零。

- (void)dealloc {
    // Cleanup table view 
    self.tableView.delegate = nil;
    self.tableView.dataSource = nil;

    // Stop network operations since their are not needed anymore.
    for (UITableViewCell *cell in [self.tableView visibleCells]) {
        [cell. listItemImage cancelImageRequestOperation];
    }
 }

在您的 cellForRowAtIndexPath 中取消图像下载,然后再使用:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"MyCellId";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    // Cancel network request
    [cell. listItemImage cancelImageRequestOperation];
    ...
}

【讨论】:

  • 我也这样做了,但是当我现在上下滚动时,我的应用程序崩溃了。当互联网连接缓慢时发生。任何想法为什么?
  • 我正在使用 UIImageView+AFNetworking 并且我认为我正在以正确的方式使用它。我也收到此消息,不知道它是什么意思:purgeIdleCellConnections: found one to purge conn = 0x1d5bb9a0
  • 你能发布你的滚动崩溃吗?您在帖子中提到的崩溃与 dealloc 不滚动有关。
  • 编辑了我的问题,我不知道你要我发布哪个代码?当我滚动是时应用程序崩溃,但我认为它与 AFNetworking 有关,因为我有一个没有图像的表格视图,它工作正常。
猜你喜欢
  • 2013-12-05
  • 1970-01-01
  • 1970-01-01
  • 2011-11-08
  • 1970-01-01
  • 2016-05-05
  • 1970-01-01
  • 2018-03-10
相关资源
最近更新 更多