问题描述
作为此问题的后续行动:,我正在为iOS7和iOS8中的 UITableView
单独执行代理。
所以,作为第一步在我的 MyTableViewController
的 viewDidLoad
中,我添加了以下代码:
[pre>
if([[[UIDevice currentDevice] systemVersion] compare:@8.0选项:NSNumericSearch]!= NSOrderedAscending)
{
[self.tableView setDelegate:[[MyTVDelegate alloc] initWithIdentifier:myTVCellIdentifier]];
}
else
{
[self.tableView setDelegate:[[MyTVDelegate7 alloc] initWithIdentifier:myTVCellIdentifier]];
}
我添加了一个标识符,因为我必须将其应用到多个查看控制器(或者我可能只为每个电视创建一个代理类,我还没有想到这一点)。
我正在使用 CoreData
,所以我的dataSource是一个 NSFetchedResultsController
。
然后,我有以下的 MyTVDelegate / myTVDelegate7
:
#importMyTVDelegate.h
@implementation MyTVDelegate
- (instancetype)initWithIdentifier:(NSString *)标识符
{
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 :]:无法识别的选择器发送到实例0x7b9dd220
2015-01-18 10:42:57.731 ***由于未捕获的异常'NSInvalidArgumentException'终止应用程序,原因:' - [__ NSArrayI tableView:estimatedHeightForRowAtIndexPath:]:无法识别的选择器在iOS8上发送到实例0x7b9dd220'
。没有崩溃。
实例0x7b9dd220是一个 NSArray
。我的预感是它崩溃了,因为 indexPath
是无效的,因为委托
和'dataSource'现在是分开的? / p>
我已经尝试将呼叫转移到 performFetch
之前或之后设置委托,但我得到相同错误。
如何解决这个问题,我应该如何将所有的 NSFetchedResultsController
代码移动到新的委托类还有?
self.tableView setDelegate:
分配一个 weak
reference;如果你没有自己的引用这个对象,它将被收集。这就是为什么你看到崩溃。系统已收集分配给您的代理的内存,然后将内存重新分配给一个 NSArray
。您的表尝试调用委托方法,因为 NSArray
不对其进行响应。
self.tableView
属性定义,定义另一个属性:
@property (strong)id
As a follow up to this question: Skip/ignore method in iOS, I'm trying to implement separate delegates for my UITableView
in iOS7 and iOS8.
So, as a first step, in viewDidLoad
of my MyTableViewController
, I added the following code:
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]];
}
I'm adding an identifier, since I will have to apply this to multiple view controllers (or I may have just create a delegate class for each TV, I haven't figured that out yet).
I'm using CoreData
, so my dataSource is an NSFetchedResultsController
.
Then, I have the following for 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
If I run this, I'm getting the following runtime error in 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'
on iOS8, there is no crash.
The instance 0x7b9dd220 is an NSArray
. My hunch is that it crashes, because the indexPath
is invalid because the delegate
and 'dataSource' are now separate?
I've tried moving the call to performFetch
to either before or after setting the delegate, but I get the same error.
How do I fix this, should I for instance move all the NSFetchedResultsController
code to the new delegate class as well?
self.tableView setDelegate:
assigns a weak
reference; if you don't hold your own reference to this object, it will get collected. This is why you're seeing the crash. The system has collected the memory that was assigned to your delegate, then reassigned the memory to an NSArray
. Your table tries to call methods on the delegate and can't because NSArray
does not respond to them.
Alongside the self.tableView
property definition, define another property:
@property (strong) id<UITableViewDelegate> myTableViewDelegate;
这篇关于为iOS7和iOS8重构UITableView代理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!