Iphone iOS insertSubview:belowSubview:与SIGABRT一起崩溃

Iphone iOS insertSubview:belowSubview:与SIGABRT一起崩溃,iphone,ios,ipad,Iphone,Ios,Ipad,我有一个自定义的TabbarViewController,它基本上隐藏了标准的选项卡视图。我附加了一个按钮,当按下它时,会在屏幕上设置菜单的动画。在长时间使用应用程序时,一切正常,但在某些情况下,它会因EXC_BAD_访问或SIGABRT而崩溃 奇怪的是,在检查menuView是否是tabbarController的子视图之前,我添加了一个用于打印tabbarController和menuView的NSLog,它在NSLog行上崩溃,在我看来,它们中的一个似乎被释放了,但没有显式调用,它们都被保

我有一个自定义的TabbarViewController,它基本上隐藏了标准的选项卡视图。我附加了一个按钮,当按下它时,会在屏幕上设置菜单的动画。在长时间使用应用程序时,一切正常,但在某些情况下,它会因EXC_BAD_访问或SIGABRT而崩溃

奇怪的是,在检查menuView是否是tabbarController的子视图之前,我添加了一个用于打印tabbarController和menuView的NSLog,它在NSLog行上崩溃,在我看来,它们中的一个似乎被释放了,但没有显式调用,它们都被保留了

这次碰撞从未在模拟器上发生过。有什么问题吗

AppDelegate.h

AppDelegate.m

这是坠机日志

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的实例变量。您有一个名为menuView的属性,但需要使用self.menuView调用此属性


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

此崩溃也应发生在模拟器上。在单击菜单中,尝试访问菜单视图。但是,从外观上看,您没有名为menuView的实例变量。您有一个名为menuView的属性,但需要使用self.menuView调用此属性


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

我认为关键在于编码样式

功能区和菜单是全局的吗?无论是否,您都不拥有菜单,而只是将menu.view指定给menuView,而不是使用self.menuView来保留。是的,我知道代码只是alloc菜单,没有发布它

在Mac上运行的模拟器上很难做到这一点,但在内存少、功能差的iPodtouch上可能更容易做到

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

将Xcode更新为最新版本。 不要为属性编写任何@synthesis代码。Xcode将@synthesis menuView=\u menuView。 如果可能,避免使用全局变量,而是在OOP中使用属性。因此,我将编写self.menuView=[[RibbonMenu alloc]init]autorelease];拥有RibbonMenu的视图以供使用。
仅供参考:

我认为关键在于编码风格

功能区和菜单是全局的吗?无论是否,您都不拥有菜单,而只是将menu.view指定给menuView,而不是使用self.menuView来保留。是的,我知道代码只是alloc菜单,没有发布它

在Mac上运行的模拟器上很难做到这一点,但在内存少、功能差的iPodtouch上可能更容易做到

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

将Xcode更新为最新版本。 不要为属性编写任何@synthesis代码。Xcode将@synthesis menuView=\u menuView。 如果可能,避免使用全局变量,而是在OOP中使用属性。因此,我将编写self.menuView=[[RibbonMenu alloc]init]autorelease];拥有RibbonMenu的视图以供使用。
仅供参考:

将值指定给menuView时,您没有使用属性,而是使用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;
    }
 }

将值指定给menuView时,您没有使用属性,而是使用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;
    }
 }

很抱歉,这两个属性都是合成的。添加到已编辑的问题中,您仍应通过setter方法访问它们,而不是直接访问。通过直接使用IVAR,您绕过了任何内存管理。@jrturton这是一个很好的观点,但这不应该与问题的粗心大意有关,这两个属性都是综合的。添加到已编辑的问题中,您仍应通过setter方法访问它们,而不是直接访问。通过直接使用IVAR,您绕过了任何内存管理。@jrturton这是一个很好的观点,但这不应该与问题的崩溃有关。您曾经将ribbon添加为子视图吗?您试图在其下方添加menuView,但它是否处于
您的视图层次结构?@rdelmar编辑的问题。Ribbon是在DidFinishLaunching中添加的,您在哪里添加Ribbon作为子视图?您试图在其下方添加menuView,但它是否在视图层次结构中?@rdelmar编辑的问题。Ribbon是在didFinishLaunchingsorry中添加的,我认为接受这个答案已经足够了^^^给你,谢谢-对不起,我认为接受这个答案已经足够了^^给你,谢谢-