好的,所以我在这里遇到了一个奇怪的问题,我在过去几个小时里一直试图解决这个问题:
我有一个简单的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;
替换它,但没有改变。
答案 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。我的坏!