У меня есть UITableView
с несколькими разделами. Каждый раздел содержит разный набор данных: номера телефонов, адреса....
Для каждого из этих наборов у меня есть модель: PhoneNumber, Address. Они совершенно разные, но имеют некоторые общие методы.
В моем UITableView
у меня есть массив, содержащий эти модели/имена классов:
NSMutableArray *имя_класса;
В viewDidLoad
моего 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: .....
Хорошо пока для инициализации. Это выглядит хорошо и работает нормально.
Затем позже в моем 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]];
Пока все хорошо, я успешно все абстрагировал, cellForRowAtIndexPath
не нужно знать, откуда берутся вещи, пока эти классы реагируют на методы получения данных для меток (в случае выше fullDesciption)
Теперь мне нужен actionButton в каждой ячейке, выполняющий какое-то действие. Чтобы убедиться, что я понял концепцию селекторов и PerformSelection, я просто быстро и грязно сделал в действии в своем классе TableView:
- (void) buttonTarget {
NSLog (@"yes");
}
И в моем методе cellForRowAtIndexPath
создал кнопку со следующей целью:
button addTarget:self action:@selector(buttonTarget) forControlEvents:UIControlEventTouchUpInside];
Хорошо, пока все хорошо, все работает, как и ожидалось. Но это не то, чего я действительно хотел. Действие должно выполняться не здесь, а в самом классе (PhoneNumber,Address,...).
Чтобы все было чисто, я сделал модель Action, содержащую иконку для кнопки, описание и селектор:
@interface Action : NSObject
@property (nonatomic, strong) NSString *description;
@property (nonatomic, strong) UIImage *icon;
@property (nonatomic ) SEL selector;
@end
В моем классе PhoneNumber (и подобных классах) действие установлено на правильный селектор:
Action *phoneAction = [[Action alloc] init];
phoneAction.description = NSLocalizedString(@"Call", @"Call button description");
phoneAction.icon = [UIImage imageNamed:@"phone"];
phoneAction.selector = @selector(callPhone);
Конечно, callPhone реализован в классе PhoneNumber.
В моем TableView я получаю действия для этой ячейки
action = [displayedRecord action];
Затем я пытаюсь использовать этот селектор в своей кнопке:
[button addTarget:displayedRecord action:[action selector] forControlEvents:UIControlEventTouchUpInside];
Но здесь что-то идет не так: мы никогда не приходим к этому методу, и я получаю следующую ошибку:
[UIDeviceWhiteColor callPhone]: в экземпляр 0x874af90 29-12-2013 23:23:03.629 отправлен нераспознанный селектор. UIDeviceWhiteColor callPhone]: нераспознанный селектор отправлен экземпляру 0x874af90'