我有一个自定义的TabbarViewController,它基本上隐藏了标准的选项卡视图。我附加了一个按钮,当按下该按钮时,它将在屏幕上创建菜单动画。长时间使用该应用程序后,一切都可以正常工作,但有时会因EXC_BAD_ACCESSSIGABRT而崩溃。

奇怪的是,当我在检查menuView是否是NSLog的子视图之前添加了tabbarController来打印menuViewtabbarController时,它在NSLog行上崩溃了(对我来说,看起来像其中一个已释放,但没有显式调用,并且它们都保留)。

该崩溃从未在模拟器上发生过。有什么问题的想法吗?

AppDelegate.h

UIButton *ribbon;
RibbonMenu* menu;
@property (nonatomic, retain) CustomTabbarController* tabbarController;
@property (nonatomic, retain) UIView* menuView;

AppDelegate.m
@synthesize tabbarController;
@synthesize menuView;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
tabbarController = [[CustomTabbarController alloc] init];
    [tabbarController setTabBarHidden:YES animated:NO];
    tabbarController.viewControllers = [NSArray arrayWithObjects: EventsNavigation, StyleNavigation, BrandNavigation, MemberNavigation, settingsNavigation, nil];

    ribbon = [UIButton buttonWithType:UIButtonTypeCustom];
    [ribbon retain];
    UIImage* img = [UIImage imageNamed:@"toppart.png"];
    [ribbon setImage:img forState:UIControlStateNormal];
    ribbon.frame = CGRectMake(234,0,86,97);
    //MENU SELECTOR
    [ribbon addTarget:self action:@selector(didClickMenu) forControlEvents:UIControlEventTouchUpInside];
    [tabbarController.view addSubview:ribbon];

    self.window.rootViewController = tabbarController;
    [self.window makeKeyAndVisible];
}


- (void) didClickMenu {
    if (!menuView) {
        menu = [[RibbonMenu alloc] init];
        menuView = menu.view;
        menuView.backgroundColor = [UIColor clearColor];
        [blinkTimer invalidate];
        ribbon.selected = NO;
    }

    if ([tabbarController.view.subviews containsObject:menuView]) {
        [self removeMenu];
    } else {
        menuView.frame = CGRectMake(235,-370,82,432);
        //**CRASH HERE**
        [tabbarController.view insertSubview:menuView belowSubview:ribbon];
        [UIView transitionWithView:menuView
                          duration:0.2
                           options:UIViewAnimationOptionCurveLinear
                        animations:^ { menuView.frame = CGRectMake(235,0,82,432);}
                        completion:nil];
    }
}

-(void) removeMenu {
    [UIView transitionWithView:menuView
                      duration:0.2
                       options:UIViewAnimationOptionCurveLinear
                    animations:^ { menuView.frame = CGRectMake(235,-370,82,432);}
                    completion:^(BOOL finished) {[menuView removeFromSuperview];}];
}

这是崩溃日志
Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x00000000, 0x00000000
Crashed Thread:  0

Last Exception Backtrace:
0   CoreFoundation                  0x35a5388f __exceptionPreprocess + 163
1   libobjc.A.dylib                 0x33677259 objc_exception_throw + 33
2   CoreFoundation                  0x35a53789 +[NSException raise:format:] + 1
3   CoreFoundation                  0x35a537ab +[NSException raise:format:] + 35
4   UIKit                           0x33313cf1 __windowForView + 157
5   UIKit                           0x33155ccd -[UIView(Hierarchy) _postMovedFromSuperview:] + 21
6   UIKit                           0x3315680d -[UIView(Internal) _addSubview:positioned:relativeTo:] + 1169
7   UIKit                           0x33172071 -[UIView(Hierarchy) insertSubview:belowSubview:] + 29
8   MyAppName                       0x000c6af3 -[AppDelegate didClickMenu] (AppDelegate.m:247)

最佳答案

当您将值分配给menuView时,您没有使用property,而是使用了menuView的iVar。

要使用该属性,应使用self将值分配给menuView。

self.menuView = menu.view;

通过访问属性,它将保留它。通过访问iVar,它不会保留它。因此,一旦您从menuView中删除superView,就有机会将其删除。
- (void) didClickMenu {
    if (!menuView)
    {
        menu = [[RibbonMenu alloc] init];
        **self.menuView = menu.view;**
        menuView.backgroundColor = [UIColor clearColor];
        [blinkTimer invalidate];
        ribbon.selected = NO;
    }
 }

07-26 09:38