簡體   English   中英

ARC自定義委托奇怪的問題

[英]ARC custom delegate strange issue

好的,所以在過去的幾個小時里,我一直想找出一個奇怪的問題:

我有一個適用於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; 調試器顯示委托仍然為零(!)但是,當我使用NSLog(@"%@", self.mvc.delegate); 我得到的指針的地址不是nil。

2-上面的代碼不起作用,因為在ModalViewController ,委托始終為nil。 因此, [delegate btnDonePressed:sender Values:values]; 將永遠不會執行。 我嘗試了所有可能導致此問題的方法,但似乎沒有任何效果。

3-我猜想對委托人有充分的參考可以解決此問題,但我不想違反此模式並引起保留周期問題。 是否私有變量ModalViewController *mvc; FirstViewController有生命周期問題嗎? 私有變量什么時候被清除? 順便說一句,我也試圖用@property (strong, nonatomic) ModalViewController *mvc;代替它@property (strong, nonatomic) ModalViewController *mvc; 但什么都沒有改變。

“我只是在這里復制了錯誤的版本。但是,這不能解決問題。(我更新了上面的代碼)”

由於您提到復制粘貼。 確保原始代碼中包含@synthesize 此問題看起來像是合成屬性與私有變量名稱的不匹配。

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

@synthesize結合聲明的屬性將使用名為delegate的私有變量。 如果您不小心遺漏了@synthesize ,則會自動創建一個名稱為_delegate的私有變量(請注意下划線)。

buttonPressed:方法中,可以直接訪問私有變量delegate 因此,由於訪問器實際上使用的是帶下划線的版本,因此該返回值始終為nil。

只需確保刪除手動聲明的變量delegate或在buttonPressed:方法中使用self.delegate 走着瞧吧。

謝謝大家的回答。 我終於找到了解決這個問題的方法。

實際上,該代碼是完全正確的。 問題是UINavigationController ,其中嵌入了Modal View Controller。

代替

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

我做

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

我不知道當您選擇嵌入到NavigationController中的ViewController時,DestinationViewController是NavigationController而不是ViewController。 我的錯!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM