UIViewController保留在ARC中

时间:2013-12-06 03:40:04

标签: objective-c uiviewcontroller automatic-ref-counting strong-references

我有一个UIViewController的子类 - > MyPopUpViewController

@protocol MyPopUpViewController Delegate;
@interface MyPopUpViewController : UIViewController
{

}
@property (nonatomic, strong) id <MyPopUpViewControllerDelegate>  delegate;

-(IBAction) buttonPressed:(id)sender;
@end

@protocol MyPopUpViewControllerDelegate
-(void) popupButtonPressed: (MyPopUpViewController*)controller;
@end

我不能将此MyPopUpViewController作为实例变量,因为这是外部的,并且可能会有很多这样的弹出窗口可以启动。到目前为止,我尝试了这个,并且由于没有被保留而在委托调用中崩溃:

MyMainViewController:

-(void)externalNotificationReceived: (NSString*) sentMessage
{    
    MyPopUpViewController *popupView = [[MyPopUpViewController alloc] init];
    popupView.delegate = self;

    [self.view addSubview:popupView.view];

    [popupView setInfo :sentMessage :@"View" :@"Okay"];
    popupView.view.frame = CGRectMake(0, -568, 320, 568);
    popupView.view.center = self.view.center;
}

-(void)popupButtonPressed:(MyPopUpViewController *)controller :(int)sentButtonNumber
{
    NSLog(@"Popup Delegate Called");

    [controller.view removeFromSuperview];
    controller.delegate = nil;
    controller = nil;
}

一旦弹出窗口出现,并且点击了ok按钮,它就会崩溃并且永远不会到达那个NSLog。我怎样才能改变

MyPopUpViewController * popupView = [[MyPopUpViewController alloc] init];

..所以它会在不使其成为实例变量的情况下保留吗?

提前致谢。

2 个答案:

答案 0 :(得分:3)

您应该通过调用addChildViewController:来进行正确的视图控制器控制。

- (void)externalNotificationReceived: (NSString*) sentMessage {    
    MyPopUpViewController *popupView = [[MyPopUpViewController alloc] init];
    popupView.delegate = self;

    [popupView setInfo :sentMessage :@"View" :@"Okay"];
    popupView.view.frame = CGRectMake(0, -568, 320, 568);
    popupView.view.center = self.view.center;

    [self addChildViewController:popupView];    
    [self.view addSubview:popupView.view];
    [popupView didMoveToParentViewController:self];
}

这将保持对视图控制器的正确引用,并正确传递各种视图控制器事件。请阅读UIViewController和“适用于iOS的View Controller编程指南”的文档中的相关内容。

顺便说一下 - 你应该更好地命名你的方法。例如:

popupButtonPressed::

应该命名为:

popupButtonPressed:buttonNumber:

答案 1 :(得分:1)

通常委托是弱引用而不是强引用。我,我自己,会将其他名称命名为不要混淆其他人。

此外,以下代码将无效:

-(void)popupButtonPressed:(MyPopUpViewController *)controller :(int)sentButtonNumber
{
    ...
    controller = nil;
}

控制器将在范围结束时自动释放(设置为nil)。