重构 iOS7 和 iOS8 的 UITableView 委托
Refactoring UITableView delegates for iOS7 and iOS8
作为这个问题的跟进:,我正在尝试在 iOS7 和 iOS8.[=27 中为我的 UITableView
实现单独的委托=]
因此,作为第一步,我在 MyTableViewController
的 viewDidLoad
中添加了以下代码:
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]];
}
我正在添加一个标识符,因为我必须将它应用于多个视图控制器(或者我可能刚刚为每台电视创建了一个委托 class,我还没有弄清楚) .
我正在使用 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
代码也移至新委托 class?
self.tableView setDelegate:
分配一个 weak
引用;如果您没有自己对该对象的引用,它将被收集。这就是您看到崩溃的原因。系统已收集分配给您的代表的内存,然后将内存重新分配给 NSArray
。您的 table 尝试调用委托的方法但不能,因为 NSArray
没有响应它们。
除了 self.tableView
属性 定义之外,定义另一个 属性:
@property (strong) id<UITableViewDelegate> myTableViewDelegate;
作为这个问题的跟进: 因此,作为第一步,我在 我正在添加一个标识符,因为我必须将它应用于多个视图控制器(或者我可能刚刚为每台电视创建了一个委托 class,我还没有弄清楚) . 我正在使用 然后,我为 如果我 运行 这个,我会在 iOS7 中收到以下 运行 时间错误: 在 iOS8,没有崩溃。 实例 0x7b9dd220 是一个 我尝试将对 我该如何解决这个问题,例如我是否应该将所有 UITableView
实现单独的委托=]
MyTableViewController
的 viewDidLoad
中添加了以下代码: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
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'
NSArray
。我的预感是它崩溃了,因为 indexPath
无效,因为 delegate
和 'dataSource' 现在是分开的?performFetch
的调用移动到设置委托之前或之后,但我遇到了同样的错误。NSFetchedResultsController
代码也移至新委托 class?
self.tableView setDelegate:
分配一个 weak
引用;如果您没有自己对该对象的引用,它将被收集。这就是您看到崩溃的原因。系统已收集分配给您的代表的内存,然后将内存重新分配给 NSArray
。您的 table 尝试调用委托的方法但不能,因为 NSArray
没有响应它们。
除了 self.tableView
属性 定义之外,定义另一个 属性:
@property (strong) id<UITableViewDelegate> myTableViewDelegate;