ARC自定义委托奇怪的问题

时间:2013-01-18 15:35:45

标签: ios ipad uiviewcontroller delegates automatic-ref-counting

好的,所以我在这里遇到了一个奇怪的问题,我在过去几个小时里一直试图解决这个问题:

我有一个简单的iPad故事板应用程序,有两个视图控制器,FirstViewController是主视图控制器,ModalViewController出现在Modal segue上,它有一个名为Done的按钮。 我正在使用ARC,并且视图控制器被指定用于iPad。

我还有一个自定义委托UIModalViewControllerDelegate,您可以将其解除模态并将数据传递回第一个视图控制器。

UIModalViewControllerDelegate.h

@protocol UIModalViewControllerDelegate <NSObject>
@required
-(void)btnDonePressed:(id)sender Values:(NSArray *)values;
@end

FirstViewController.h

@interface FirstViewController : UIViewController <UIModalViewControllerDelegate> {    
@private
    ModalViewController *mvc;
}
@end

FirstViewController.m

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
// Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    mvc = [segue destinationViewController];
    mvc.delegate = self;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma UIModalViewControllerDelegate

-(void)btnDonePressed:(id)sender Values:(NSArray *)values {
        ...
}

ModalViewController.h

@interface ModalViewController : UIViewController {
    __weak id<UIModalViewControllerDelegate> delegate;
}

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

ModalViewController.m

@implementation ModalViewController

@synthesize delegate;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(buttonPressed:)];
}

-(void) buttonPressed:(id) sender {
    [delegate btnDonePressed:sender Values:values];
}

现在,有几个非常有趣的问题:

1-在准备segue时,在设置self.mvc.delegate = self;之后,调试器显示委托仍为nil(!)但是,当我使用NSLog(@"%@", self.mvc.delegate);时,我得到了指针的地址不是零。

2-上面的代码不起作用,因为在ModalViewController中委托总是为零。因此,[delegate btnDonePressed:sender Values:values];永远不会执行。我尝试了所有可能导致这个问题的事情,但似乎没有任何效果。

3-我想对委托有强有力的参考可以解决这个问题,但我不想违反该模式并导致保留周期问题。 ModalViewController *mvc;中的私有变量FirstViewController是否存在生命周期问题?私有变量何时被填满?顺便说一下,我也尝试用@property (strong, nonatomic) ModalViewController *mvc;替换它,但没有改变。

2 个答案:

答案 0 :(得分:0)

  

“我刚刚在这里复制了错误的版本。但是,这并没有解决问题。(我更新了上面的代码)”

因为你提到了复制粘贴。确保原始代码中包含@synthesize。此问题看起来像是合成属性与私有变量名称不匹配。

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

@synthesize一起声明的属性将使用名为delegate的私有变量。如果您在事故中遗漏@synthesize,将自动创建名为_delegate的私人变量(请注意下划线)。

buttonPressed:方法中,您可以直接访问私有变量delegate。因此,访问者实际上使用了下划线版本,因此可能总是返回nil。

只是为了确保删除手动声明的变量delegate或使用self.delegate方法中的buttonPressed:。看看会发生什么。

答案 1 :(得分:0)

感谢大家的回答。我终于找到了解决这个问题的方法。

实际上,代码完全正确。问题是UINavigationController,其中嵌入了模态视图控制器。

而不是

myModalWindowViewController = [segue destinationViewController];
myModalWindowViewController.delegate = self;

我做

UINavigationController *navigationController = [segue destinationViewController];
myModalWindowViewController = (MyModalWindowViewController *)[navigationController.viewControllers objectAtIndex:0];
myModalWindowViewController.delegate = self;

我不知道当你转向嵌入在NavigationController中的ViewController时,DestinationViewController是NavigationController而不是ViewController。我的坏!