选择器和PerformSelector

时间:2013-12-29 22:48:13

标签: ios uitableview selector

我有一个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'

2 个答案:

答案 0 :(得分:1)

听起来你有一个僵尸。当您将某个操作发送到一个没有意义的对象时,通常意味着您的对象在被发送消息之前被释放。

在您的情况下,您将“displayedRecord”添加为按钮的目标。

为了使其工作,您需要在按钮对象的生命周期内对displayedRecord调用保持强引用。拥有你的displayedRecord对象的是什么?

如果您无法通过查看代码进行调试,可以使用僵尸工具来试图找出它。

答案 1 :(得分:0)

在无法识别的选择器错误中,您将消息发送到名为UIDeviceWhiteColor的对象。该类是否有一个名为callPhone的方法?在我看来,displayedRecord并没有指向你认为它的对象。