我有一个定制的TabbarViewController,它基本上隐藏了标准的选项卡视图。我附加了一个按钮,当按下它时,会将一个菜单动画到屏幕上。在长时间使用应用程序时,一切都很好,但在某一时刻,它会与EXC_BAD_ACCESS或SIGABRT崩溃。
奇怪的是,当我在检查NSLog是否是tabbarController的子视图之前添加了一个用于打印tabbarController和menuView的menuView时,它在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)发布于 2013-01-21 16:51:14
当您将值赋值给menuView时,您不是使用属性,而是使用iVar of menuView。
要使用该属性,应使用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;
}
}发布于 2013-01-14 05:06:18
这种碰撞也应该发生在模拟器上。在didClickMenu中,您尝试访问menuView。但是,从外观上看,您没有一个名为menuView的实例变量。您有一个名为的menuView属性,但您需要使用self.menuView调用该属性。
或者,如果您使用的是Xcode 4.4或更高版本,并且没有合成属性,编译器将为您创建一个实例变量。这个实例变量与属性具有相同的名称,但是带有_前缀--在本例中是_menuView。
发布于 2013-01-18 08:43:38
我认为关键是编码风格的.
丝带和菜单是全球性的吗?不管您是否拥有菜单,您只是将menu.view分配给menuView,而不是使用self.menuView来保留。是的,我知道代码只是分配菜单,没有释放它。
在运行在Mac上的模拟器上很难实现,但在内存较少和能力较差的iPod触摸上可能更容易。
正如我们所知,EXC_BAD_ACCESS是由于访问释放的对象。如果我是你,我会:
self.menuView = [[[RibbonMenu alloc] init] autorelease];来拥有RibbonMenu的视图以供使用。金融时报:http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html
https://stackoverflow.com/questions/14313507
复制相似问题