首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >iOS插入子视图:下面的SIGABRT :SIGABRT崩溃

iOS插入子视图:下面的SIGABRT :SIGABRT崩溃
EN

Stack Overflow用户
提问于 2013-01-14 04:59:01
回答 3查看 1.1K关注 0票数 1

我有一个定制的TabbarViewController,它基本上隐藏了标准的选项卡视图。我附加了一个按钮,当按下它时,会将一个菜单动画到屏幕上。在长时间使用应用程序时,一切都很好,但在某一时刻,它会与EXC_BAD_ACCESSSIGABRT崩溃。

奇怪的是,当我在检查NSLog是否是tabbarController的子视图之前添加了一个用于打印tabbarControllermenuView的menuView时,它在NSLog行上崩溃了(在我看来,它们中有一个已经发布,但是没有显式调用,它们都被保留了)。

这起坠机事件从未发生在模拟器上。对怎么了有什么想法吗?

AppDelegate.h

代码语言:javascript
复制
UIButton *ribbon;
RibbonMenu* menu;
@property (nonatomic, retain) CustomTabbarController* tabbarController;
@property (nonatomic, retain) UIView* menuView;

AppDelegate.m

代码语言:javascript
复制
@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];}];
}

这是崩溃日志

代码语言:javascript
复制
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)
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-01-21 16:51:14

当您将值赋值给menuView时,您不是使用属性,而是使用iVar of menuView

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

代码语言:javascript
复制
self.menuView = menu.view;

通过访问属性,它将保留它。通过访问iVar,它将不会保留它。因此,一旦您从menuViewsuperView中删除它,它就有可能被删除。

代码语言:javascript
复制
- (void) didClickMenu {
    if (!menuView)
    {
        menu = [[RibbonMenu alloc] init];
        **self.menuView = menu.view;**
        menuView.backgroundColor = [UIColor clearColor];
        [blinkTimer invalidate];
        ribbon.selected = NO;
    }
 }
票数 1
EN

Stack Overflow用户

发布于 2013-01-14 05:06:18

这种碰撞也应该发生在模拟器上。在didClickMenu中,您尝试访问menuView。但是,从外观上看,您没有一个名为menuView的实例变量。您有一个名为的menuView属性,但您需要使用self.menuView调用该属性。

或者,如果您使用的是Xcode 4.4或更高版本,并且没有合成属性,编译器将为您创建一个实例变量。这个实例变量与属性具有相同的名称,但是带有_前缀--在本例中是_menuView

票数 2
EN

Stack Overflow用户

发布于 2013-01-18 08:43:38

我认为关键是编码风格的.

丝带和菜单是全球性的吗?不管您是否拥有菜单,您只是将menu.view分配给menuView,而不是使用self.menuView来保留。是的,我知道代码只是分配菜单,没有释放它。

在运行在Mac上的模拟器上很难实现,但在内存较少和能力较差的iPod触摸上可能更容易。

正如我们所知,EXC_BAD_ACCESS是由于访问释放的对象。如果我是你,我会:

  1. 将Xcode更新为最新版本。
  2. 不要为财产写任何@合成代码。Xcode将@合成menuView = _menuView。
  3. 如果可能的话,避免使用全局变量,而是在OOP中使用属性。因此,我会编写self.menuView = [[[RibbonMenu alloc] init] autorelease];来拥有RibbonMenu的视图以供使用。

金融时报:http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14313507

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档