我的UINavigationControllerDelegate在app加载主视图后被删除了

时间:2015-02-28 11:08:20

标签: ios objective-c

我想为UINavigation控制器实现自定义动画。

我在Appdelegate中添加了一些属性:

@interface MyAppDelegate : UIResponder <UIApplicationDelegate> {
...
// for custrom navigation transition animation
@property (strong, nonatomic) UINavigationController *AppNavigationController;
...
@end
在didFinishLaunchingWithOptions中:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
self.AppNavigationController = (UINavigationController *)((REFrostedViewController *)self.window.rootViewController).contentViewController;
        MyNavigationControllerDelegate * naviDelegate = [[MyNavigationControllerDelegate alloc] init];
self.AppNavigationController.delegate = naviDelegate;
    }
...
}

调试时,到目前为止,我可以看到委托:

(lldb) po self.AppNavigationController
<UINavigationController: 0x14f52bb90>

(lldb) po self.AppNavigationController.delegate
<MyNavigationControllerDelegate: 0x17424c5a0>

当我的主视图控制器加载时,我仍然可以看到

(lldb) po 0x14f52bb90
<UINavigationController: 0x14f52bb90>

但是当试图访问其委托的0x14f52bb90时,

(lldb) po [0x14f52bb90 delegate]
2015-02-28 18:54:14.724 MyApp[1995:489717] *** -[MyNavigationControllerDelegate respondsToSelector:]: message sent to deallocated instance 0x17424c5a0
0x000000017424c5a0

我不知道为什么委托被解除分配,以及如何解决它。有什么想法吗?

MyNavigationControllerDelegate初始化代码:

-(id)init {
    self = [super init];
    if (self) {
        self.pushAnimator = [[PushAnimator alloc] init];
        self.popAnimator = [[PopAnimator alloc] init];
        UIApplication * app = [UIApplication sharedApplication];
        MyAppDelegate *appDelegate = (MyAppDelegate *)app.delegate;
        self.navigationController = appDelegate.AppNavigationController;
        UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
        [self.navigationController.view addGestureRecognizer:panRecognizer];
    }
    return self;
}

进一步崩溃追踪:

(lldb) bt
* thread #1: tid = 0x778f5, 0x0000000184a72440 CoreFoundation`___forwarding___ + 968, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=1, subcode=0x184a72440)
  * frame #0: 0x0000000184a72440 CoreFoundation`___forwarding___ + 968
    frame #1: 0x0000000184976b6c CoreFoundation`_CF_forwarding_prep_0 + 92
    frame #2: 0x00000001892d1d4c UIKit`-[UINavigationController _startTransition:fromViewController:toViewController:] + 908
    frame #3: 0x00000001892d16dc UIKit`-[UINavigationController _startDeferredTransitionIfNeeded:] + 640
    frame #4: 0x00000001892d13fc UIKit`-[UINavigationController __viewWillLayoutSubviews] + 56
    frame #5: 0x00000001892d137c UIKit`-[UILayoutContainerView layoutSubviews] + 200

1 个答案:

答案 0 :(得分:1)

我的猜测是delegate上的AppNavigationController属性被定义为@property(assign)(或没有默认为assign的任何修饰符),因此-application:didFinishLoadingWithOptions时完成后,delegate被解除分配,因为它不会保留在任何地方。

如果是这种情况,您可以使用@property(strong)进行修复。

修改

UINavigationController属性delegate定义为assign,因此您需要在其他地方保留委托,我建议您这样做:

MyAppDelegate

@interface MyAppDelegate : UIResponder <UIApplicationDelegate> {
...
@property(strong) MyNavigationControllerDelegate* naviDelegate;   
...
@end

didFinishlaunchingWithOptions

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...

self.AppNavigationController = (UINavigationController *)((REFrostedViewController *)self.window.rootViewController).contentViewController;
self.naviDelegate = [[MyNavigationControllerDelegate alloc] init];
self.AppNavigationController.delegate = self.naviDelegate;

...
}