2013-11-21 3 views
8

У меня есть контроллер представления с методом делегата, который должен быть вызван, но это не так?Метод делегата не называется?

NotifyingViewController.h

@protocol NotifyingViewControllerDelegate <NSObject> 
@required 
- (void)iWasAccepted; 
@end 

@interface NotifyingViewController : UIViewController 

@property (nonatomic, weak) id<NotifyingViewControllerDelegate> delegate; 

NotifyingViewController.m

-(void)someMethod{ 
     [self.delegate iWasAccepted]; 
     [self dismissViewControllerAnimated:YES completion:nil]; 
} 

NotifiedViewController.h

#import "NotifyingViewController.h" 
@interface NotifiedViewController : UIViewController <NotifyingViewControllerDelegate> 

NotifiedViewController.m

-(void)iWasAccepted{ 
    [self saveIntoDB]; 
    NSLog(@"DELEGATE RAN"); 
} 

По какой-то причине контроллер, который должен быть уведомлен, не является. Контроллер уведомлений отклоняет значение метода, который предупреждает о запуске функции делегата, но делегат не запускает эту функцию, потому что это не NSLog. Любые идеи почему?

+3

Где вы назначаете 'NotifiedViewController' как делегата NotifyingViewController'? –

+0

Ваш 'делегат' является ссылкой« слабый »(как и должно быть); вы уверены, что он не стал «ноль», когда вы его называете? – Arkku

+0

@ 0x7fffffff: Я думал, вам нужно всего лишь сделать это в UIViewController: NSObject <> part? Есть ли еще что-то еще? Извините, я новичок в методах делегирования :) –

ответ

23

Вы не можете просто указать, что объект соответствует протоколу. Вы также должны назначить этот объект в качестве делегата. Когда вы назначаете/инициализируете экземпляр NotifyingViewController, установите его делегат на себя, и вы должны быть в порядке.

NotifyingViewController *notifyingInstance = [[NotifyingViewController alloc] init]; 
[notifyingInstance setDelegate:self]; 

Это важно как это сделать, и указать, что класс соответствует протоколу, который вы уже делаете с этой линией.

@interface NotifiedViewController : UIViewController <NotifyingViewControllerDelegate> 

Кроме того, при вызове методов делегата, это хорошая практика, чтобы обернуть вызовы функций в respondsToSelector: проверок.

if ([self.delegate respondsToSelector:@selector(iWasAccepted)]) { 
    [self.delegate iWasAccepted]; 
} 
+0

Не могли бы вы объяснить, почему рекомендуется использовать последнюю упомянутую практику? –

+0

@DariusMiliauskas Вот как вы проверяете во время выполнения, что делегат фактически реализовал этот метод. Даже если вы помечаете метод, как требуется в вашем протоколе, вы фактически не обязаны его реализовывать (вы получите предупреждение, если вы этого не сделаете). И если у вас есть нереализованный метод делегата (необязательный или обязательный), и вы пытаетесь вызвать этот метод, среда выполнения будет через «NSInvalidArgumentException» и будет жаловаться на то, как «нераспознанный селектор отправляется экземпляру». Короче говоря, эта проверка позволяет вызывать только вызов метода, если экземпляр делегирования фактически реализует его. –

+0

Я реализую его, но не вхожу в условие if ([self.delegate отвечаетSoSelector: @selector (iWasAccepted)]) { [self.delegate iWasAccepted]; } как его решить? –

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