【问题标题】:Refactoring UITableView delegates for iOS7 and iOS8为 iOS7 和 iOS8 重构 UITableView 委托
【发布时间】:2015-01-18 16:00:52
【问题描述】:

作为对这个问题的跟进:Skip/ignore method in iOS,我正在尝试在 iOS7 和 iOS8 中为我的UITableView 实现单独的委托。

因此,作为第一步,我在MyTableViewControllerviewDidLoad 中添加了以下代码:

if ([[[UIDevice currentDevice] systemVersion] compare: @"8.0" options: NSNumericSearch] != NSOrderedAscending)
{
    [self.tableView setDelegate: [[MyTVDelegate alloc] initWithIdentifier: myTVCellIdentifier]];
}
else
{
    [self.tableView setDelegate: [[MyTVDelegate7 alloc] initWithIdentifier: myTVCellIdentifier]];
}

我正在添加一个标识符,因为我必须将它应用于多个视图控制器(或者我可能只是为每台电视创建了一个委托类,我还没有弄清楚)。

我使用的是CoreData,所以我的数据源是NSFetchedResultsController

然后,我有以下MyTVDelegate/myTVDelegate7

#import "MyTVDelegate.h"

@implementation MyTVDelegate

- (instancetype)initWithIdentifier: (NSString *) identifier
{
    if ([super init])
    {
        self.identifier = identifier;
    }

    return self;
}

@end

@implementation MyTVDelegate7

- (CGFloat)tableView: (UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath *)indexPath
{
    return 44;
}

- (CGFloat)tableView: (UITableView *)tableView estimatedHeightForRowAtIndexPath: (NSIndexPath *)indexPath
{
    return UITableViewAutomaticDimension;
}

@end

如果我运行它,我会在 iOS7 中收到以下运行时错误:

2015-01-18 10:42:51.894  -[__NSArrayI tableView:estimatedHeightForRowAtIndexPath:]: unrecognized selector sent to instance 0x7b9dd220
2015-01-18 10:42:57.731  *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI tableView:estimatedHeightForRowAtIndexPath:]: unrecognized selector sent to instance 0x7b9dd220'

在 iOS8 上,没有崩溃。

实例 0x7b9dd220 是一个NSArray。我的预感是它崩溃了,因为 indexPath 无效,因为 delegate 和 'dataSource' 现在是分开的?

我尝试将调用 performFetch 移动到设置委托之前或之后,但我得到了同样的错误。

我该如何解决这个问题,例如,我是否应该将所有 NSFetchedResultsController 代码也移动到新的委托类中?

【问题讨论】:

  • 这可能无关,但在你的initWithIdentifier 中你需要将self 分配给[super init] 的结果:if (self = [super init])...
  • 好收获!但正如你所说,这与问题无关。
  • 该错误消息暗示 tableView 委托是 NSArray 的一个实例。你能登录self.tableView.delegate看看它是什么类吗?
  • 对我来说看起来不错:po self.tableView.delegate <MyTVDelegate7: 0x7c4877e0> 也许我还需要为我的fetchedResultsControler 调整一些东西?
  • 你真正的问题是你没有留住你的代表。您可能需要在 MyTableViewController 中创建一个指向您的 MyTVDelegate7(或 MyTVDelegate)实例的强属性。

标签: ios objective-c uitableview delegates


【解决方案1】:

self.tableView setDelegate: 分配一个weak 引用;如果您没有自己对该对象的引用,它将被收集。这就是您看到崩溃的原因。系统已收集分配给您的代理人的内存,然后将内存重新分配给NSArray。您的表尝试调用委托上的方法但不能,因为 NSArray 没有响应它们。

除了self.tableView 属性定义,定义另一个属性:

@property (strong) id<UITableViewDelegate> myTableViewDelegate;

【讨论】:

  • 根据上面@rdelmar 的评论,我添加了这个:@property (nonatomic, strong) MyTVDelegate *delegate; @property (nonatomic, strong) MyTVDelegate7 *delegate7;,所以一个用于iOS7,一个用于iOS8,效果很好。该解决方案与您的解决方案有何不同?
  • 你真的只需要一个委托句柄,因为你只实例化了其中一个。
  • 优秀。我确实有另一个后续问题,我在这里发布:stackoverflow.com/questions/28101377/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-11
  • 2012-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多