2015-07-05 3 views
-2

Я хотел бы создать UITableViewController в другом контроллере, а также передать ему метод с этого контроллера. Я уже читал, что это может быть достигнуто с помощью @selector. Теперь я попытался следующие:Выполнение селектора в другом классе

TimeController.m

- (void)choseTime{ 
    SelectOptionController *selectController = [[SelectOptionController alloc] initWithArray:[Time SQPFetchAll] andSelector:@selector(timeSelected)]; 
    [self.navigationController pushViewController:selectController animated:true]; 
} 

- (void) timeSelected{ 
    NSLog(@"Time selected!"); 
} 

SelectOptionController.h

@interface SelectOptionController : UITableViewController 

@property (nonatomic, strong) NSMutableArray *dataset; 
@property (nonatomic) SEL selectedMethod; 

-(id)initWithArray: (NSMutableArray *) myArray andSelector: (SEL) selectedMethod; 

SelectOptionController.m

- (id)initWithArray: (NSMutableArray *) myArray andSelector: (SEL) selectedMethod{ 
    self = [super initWithStyle:UITableViewStyleGrouped]; 
    if(self) { 
     self.dataset = myArray; 
     self.selectedMethod = selectedMethod; 
    } 
    return self; 
} 

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 
    [self performSelector:self.selectedMethod]; 
    [self.navigationController popViewControllerAnimated:true]; 
} 

Однако, когда получает выделена ячейка, следующая исключение:

-[SelectOptionController timeSelected]: unrecognized selector sent to instance 0x1450f140 

Что я здесь делаю неправильно? Любая помощь будет высоко оценен.

+1

Вопросы, требующие помощи по отладке («почему этот код не работает?») Должны включать в себя желаемое поведение, конкретную проблему или ошибку и кратчайший код, необходимый для воспроизведения в самом вопросе. –

ответ

3

Вы вызываете timeSelected на self, который фактически является SelectOptionController, но метод timeSelected существует в классе TimeController.

Предполагая, что вы не хотите переместить timeSelected в SelectOptionController, вам необходимо передать ссылку на TimeController на новый SelectOptionController и вызвать селектор. Селектор - это просто ссылка на метод, а не сам метод. Вероятно, вы захотите также сохранить его как слабую ссылку.

E.g.

@interface SelectOptionController : UITableViewController 

@property (nonatomic, strong) NSMutableArray *dataset; 
@property (nonatomic) SEL selectedMethod; 
@property (nonatomic, weak) TimeController *timeController; 

И

- (id)initWithArray: (NSMutableArray *) myArray andSelector: (SEL) selectedMethod timeController:(TimeController*)timeController { 
    self = [super initWithStyle:UITableViewStyleGrouped]; 
    if(self) { 
     self.dataset = myArray; 
     self.selectedMethod = selectedMethod; 
     self.timeController = timeController; 
    } 
    return self; 
} 

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 
    [self.timeController performSelector:self.selectedMethod]; 
    [self.navigationController popViewControllerAnimated:true]; 
} 

Со всем, что сказал выше будет получить код работает, но это не особенно хорошая картина. Я бы предложил вам изучить Prototypes and Delegates для реализации этого поведения или, если вы хотите передать этот метод, сделайте некоторое исследование на Blocks. Но, надеюсь, это поможет вам лучше понять, как работают селекторы.

+0

Спасибо, что обратились за помощью. То, что я хочу сделать, это нажать TableViewController и использовать его как Pickerview, чтобы пользователь мог выбрать строку. Когда строка выбрана, я хочу, чтобы эти данные передавались родительскому виду, поэтому я могу использовать его там. Есть ли лучший способ сделать это, а затем передать селектор? – Tomzie

+0

Я бы выполнил протокол для вашего SelectOptionController и слабое свойство делегата. Протокол в основном определяет метод/s (и/или свойства), который должен иметь ваш делегат. Когда вы запускаете SelectOptionController, установите делегат на 'self' (т. Е. TimeController) и убедитесь, что TimeController соответствует вашему вновь созданному протоколу. Затем вы можете вызвать метод, который вы определили в своем протоколе для своего делегата (из SelectOptionController). Если раньше вы не работали с протоколами, я бы предложил сделать немного исследований о том, как они работают. – JoGoFo

Смежные вопросы