2013-07-16 1 views
-2

В конечном итоге я хочу написать приложение iOS, включающее ALAssetsLibrary, но, как первый шаг к пониманию делегирования, я пытаюсь передать простое сообщение между двумя контроллерами представлений. По какой-то причине я не могу передать сообщение. В частности, объект делегата (derpy) не существует (if(self.derpy) возвращает NO)).Почему мой объект-делегат не отвечает на вызовы методов?

Я задал тот же вопрос на форумах Apple, и мне сказали, что я должен использовать segues и устанавливать свойства/методы вызова, используя self.child, но это кажется странным. Если бы я передавал сообщения с использованием родительских/дочерних свойств, мог ли я по-прежнему создавать свои представления в Interface Builder? Как только у меня установлены два представления, скажите внутри UINavigationController, я не уверен, как на самом деле «подключить их», чтобы я мог передавать сообщения между ними. Извините, если вопрос слишком широк.

Вот контроллер я объявляю протокол в (называемой PickerViewController):

Интерфейс:

#import <UIKit/UIKit.h> 
#import <AssetsLibrary/AssetsLibrary.h> 

@protocol DerpDelegate <NSObject> 
@required 
- (void) test; 
@end 

@interface PickerViewController : UIViewController 

@property (nonatomic, assign) id<DerpDelegate> derpy; 

@end 

Реализация:

#import "PickerViewController.h" 

    @interface PickerViewController() 
    @end 

    @implementation PickerViewController 

    - (void)viewDidLoad 
    { 
     [super viewDidLoad];  
     if (self.derpy) {   // If the delegate object exists 
      [self.derpy test]; // send it this message 
     } else { 
      NSLog(@"Still not working.");  // This always returns (i.e., self.derpy doesn't exist) 
     } 
    } 

Делегат контроллер интерфейса (MainViewController):

#import <UIKit/UIKit.h> 
#import "PickerViewController.h" 

@interface MainViewController : UIViewController <DerpDelegate> // public promise to implement delegate methods 
@property (strong, nonatomic) PickerViewController *picker; 

- (void) test; 

@end 

И, наконец, контроллер делегат (MainViewController) реализация:

#import "MainViewController.h" 
#import "PickerViewController.h" 

@interface MainViewController() 
@end 

@implementation MainViewController 

// Here's that method I promised I'd implement 

- (void) test{ 
    NSLog(@"Test worked.");  // This never gets called 
} 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.picker.derpy = self; 

//lazy instantiation 
- (PickerViewController *) picker{ 
if(!_picker) _picker = [[PickerViewController alloc]init]; 
return _picker; 
} 

EDIT: Большое спасибо rydgaze указал мне в правильном направлении с self.picker.derpy = self, но по какой-то причине, все еще не работает должным образом. Важно отметить, что после того, как это свойство было установлено, if(self.picker.derpy) возвращает YES из MainViewController. Но if(self.derpy) все еще возвращает NO при вызове изнутри PickerViewController's viewDidLoad. Как может существовать и не существовать одновременно?

+0

По какой-то причине мои угловые скобки не появляются. Нужно ли мне как-то сбежать от них? – jefflovejapan

+0

просто используйте кнопку формата кода с выбранным кодом. и почему все эти свободные линии? – vikingosegundo

+0

(Кнопка формата кода - это кнопка '{}' над экраном ввода текста. Выделите свой код и нажмите эту кнопку.) –

ответ

2

Вы должны быть уверены, что вы устанавливаете делегат в экземпляре контроллера вида, который вы помещаете на экран. Если вы используете навигацию контроллер и перетекает идти между MainViewController и PickerViewController, то вы должны установить делегат в prepareForSegue:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    self.picker = (PickerViewController *)segue.destinationViewController; 
    self.picker.derpy = self; 
} 
+0

Большое вам спасибо! – jefflovejapan

1

Необходимо сначала заполнить делегат.

В принципе, ваш MainViewController shoudl в somepoint сделать

picker.derpy = self;

Затем, когда делегат пожары в PickerViewController, обратный вызов будет.

Edit: Хорошая практика, чтобы сделать что-то подобное в PickerViewController

@property (nonatomic, assign) id<DerpDelegate > derpy; 

и в вашем MainViewController показывают, что вы реализуете делегат

@interface MainViewController : UIViewController<DerpDelegate> 

В конце концов в вашей реализации MainViewController

У вас будет что-то вроде

picker = [[PickerViewController alloc]init]; 
picker.derpy = self; 
[picker doYourThing]; 

Как только сборщик будет готов, он может захотеть вернуть результаты с помощью делегата.

+0

Это замечательно, но по какой-то причине сообщение все еще не передается. Критически, если (self.picker.derpy) возвращает YES внутри MainViewController, но если (self.derpy) возвращает NO внутри PickerViewController. У вас есть идея, почему это было бы? – jefflovejapan

+0

Я думаю, будет полезно понять, что именно делает делегация. Делегат по существу является указателем на объект для отправки сообщения (a.k.a вызывает функцию). Поэтому, если объект (делегат) не заполнен, вы не можете вызвать функцию. Взгляните на эту ссылку: http://alexefish.com/post/15966868557/understanding-and-creating-delegates-in-objective-c – rydgaze

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

  • Нет связанных вопросов^_^