为什么我的委托对象没有响应方法调用?

时间:2013-07-16 22:05:00

标签: ios objective-c delegation

我最终想要编写一个包含ALAssetsLibrary的iOS应用程序,但作为了解委托的第一步,我试图在两个视图控制器之间传递一条简单的消息。出于某种原因,我似乎无法传递消息。特别是,委托对象(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;
}
编辑:非常感谢rydgaze用self.picker.derpy = self指示我正确的方向,但由于某种原因,事情仍然无法正常工作。重要的是,一旦设置了该属性,if(self.picker.derpy)将从MainViewController返回YES。但是当从PickerViewController的if(self.derpy)内部调用时,NO仍然返回viewDidLoad。该物业如何存在而不是同时存在?

2 个答案:

答案 0 :(得分:2)

您需要确保在屏幕上放置的视图控制器实例上设置委托。如果您正在使用导航控制器并在SIMATICViewController和PickerViewController之间切换,那么您应该在prepareForSegue中设置委托:

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

答案 1 :(得分:1)

您需要先填充代理人。

基本上,你的MainViewController在某个地方做了一个

picker.derpy = self;

然后当代理人在PickerViewController中触发时,将发生回调。

编辑: 一个好的做法是做一些像PickerViewController

这样的事情
@property (nonatomic, assign) id<DerpDelegate > derpy;

并在MainViewController中指示您将实现委托

@interface MainViewController : UIViewController<DerpDelegate>

最终在您的MainViewController实现

您将拥有类似

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

一旦选择器全部完成,它可能希望使用委托返回结果。