我有一个UITableView
有几个部分。每个部分包含一组不同的数据:phoneNumbers,address ....
对于每个集合,我都有一个模型:PhoneNumber,Address。它们完全不同,但有一些共同的方法。
在我的UITableView
我有一个包含这些模型/类名的数组:
NSMutableArray * classNames;
在我viewDidLoad
的{{1}}中,我为所有这些部分做了一些初始化:
UITableView
我再次为所有其他部分/模型执行此操作:
//section 1: PhoneNumbers
phoneNumbers = [PhoneNumbers getAllIDs];
if (phoneNumbers && (phoneNumbers.count >0)) {
[classNames addObject:@"PhoneNumber"];
[dataIDs addObject:phoneNumbers];
}
目前为止初始化正常。这看起来不错,工作正常。
然后在我的 //section 2: Addresses
addresses = [Address getAllIDs];
if (addresses && (addresses.count >0)) {
[classNames addObject:@"Address"];
[dataIDs addObject:addresses];
}
// section 3: .....
中我通过这些ID检索实际数据
cellForRowAtIndexPath
然后我弄清楚我们要在哪个类中获取实际数据:
NSInteger section = [indexPath section];
NSInteger row = [indexPath row];
NSArray *rows = [dataIDs objectAtIndex:section];
NSNumber *recordID = [rows objectAtIndex:row];
并获取数据以填充单元格。
Class displayedDataClass = NSClassFromString ([classNames objectAtIndex:section]);
然后我可以使用以下方法在我的单元格中设置标签:
id displayedRecord = [[displayedDataClass alloc] init];
[displayedRecord getByID:recordID];
到目前为止,我成功地抽象了所有内容,[cell.someLabel setText:[displayRecord fullDesciption]];
不需要知道事物的来源,只要这些类响应检索标签数据的方法(在这种情况下)以上fullDesciption)
现在我需要在每个Cell执行某种操作时使用actionButton 为了确保我理解了选择器和performSelection的概念,我只是在我的TableView类中快速而又脏了:
cellForRowAtIndexPath
在我的- (void) buttonTarget {
NSLog (@"yes");
}
方法中创建了一个具有以下目标的按钮:
cellForRowAtIndexPath
好的,到目前为止一切顺利,事情就像预期的那样。但这不是我真正想要的。此操作不应在此处执行,而应在实际的类中执行(PhoneNumber,Address,...)。
为了保持清洁,我制作了一个模型动作,包含按钮的图标,描述和选择器:
button addTarget:self action:@selector(buttonTarget) forControlEvents:UIControlEventTouchUpInside];
在我的PhoneNumber类(和类似的类)中,操作设置为正确的选择器:
@interface Action : NSObject
@property (nonatomic, strong) NSString *description;
@property (nonatomic, strong) UIImage *icon;
@property (nonatomic ) SEL selector;
@end
当然,callPhone是在PhoneNumber类中实现的。
在我的TableView中,然后获取该单元格的操作
Action *phoneAction = [[Action alloc] init];
phoneAction.description = NSLocalizedString(@"Call", @"Call button description");
phoneAction.icon = [UIImage imageNamed:@"phone"];
phoneAction.selector = @selector(callPhone);
然后我尝试在我的Button中使用该选择器:
action = [displayedRecord action];
但是这里出了问题:我们从未到过那种方法而且我得到以下错误:
[UIDeviceWhiteColor callPhone]:发送到实例的无法识别的选择器 0x874af90 2013-12-29 23:23:03.629 thinx [27242:907] * 终止应用 由于未捕获的异常'NSInvalidArgumentException',原因: ' - [UIDeviceWhiteColor callPhone]:发送到的无法识别的选择器 实例0x874af90'
答案 0 :(得分:1)
听起来你有一个僵尸。当您将某个操作发送到一个没有意义的对象时,通常意味着您的对象在被发送消息之前被释放。
在您的情况下,您将“displayedRecord”添加为按钮的目标。
为了使其工作,您需要在按钮对象的生命周期内对displayedRecord调用保持强引用。拥有你的displayedRecord对象的是什么?
如果您无法通过查看代码进行调试,可以使用僵尸工具来试图找出它。
答案 1 :(得分:0)
在无法识别的选择器错误中,您将消息发送到名为UIDeviceWhiteColor的对象。该类是否有一个名为callPhone的方法?在我看来,displayedRecord并没有指向你认为它的对象。