EXC_BAD_ACCESS in [window addSubview:viewcontroller.view]
I have two universal applications... one is giving me an EXC_BAD_ACCESS error when I do this in the app delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
ScrollViewController *vc = [[ScrollViewController alloc] init];
[window addSubview:vc.view]; // EXC_BAD_ACCESS here
[window makeKeyAndVisible];
return YES;
}
I do exactly the same (same code, same scroll view controller class) in my other application and get no errors... my scroll view loads fine.
This problem is driving me insane. Here is the ScrollViewController Implementation:
@implementation Scr开发者_如何转开发ollViewController
- (void)loadView {
[super loadView];
UIScrollView *s = [[UIScrollView alloc] initWithFrame:[[self view] bounds]];
NSArray *a = [[NSBundle mainBundle] loadNibNamed:@"JCEKKeyboard" owner:self options:nil];
UIView *v = [a objectAtIndex:0];
[s setContentSize:CGSizeMake(400, 500)];
[s addSubview:v];
[[self view] addSubview:s];
}
Remember that when you add subviews i.e. [someView addSubview:someOtherView]
, you are adding potentially a whole graph of subviews (the subviews of someOtherView
). If someView
is visible it will trigger a render on the new graph of the subview you've added. So if any of the subviews in the new graph are not correctly retained, you can get this error. You must test the entire view hierarchy you're adding.
Use the following gdb commands in your console:
To test if an individual object is valid
po [someView description]
To test the subviews of someView
po [someView subviews]
To test individual subviews (for instance the first subview element 0)
po [[someView subviews] objectAtIndex:0]
Finally to test an entire view hierarchy at once
po [someView recursiveDescription]
These commands, especially recursiveDescription
, are also very useful for troubleshooting layout issues.
init shouldn't be creating the view, loadView does that. Calling the view getter (vc.view) when view is nil will cause loadView to be invoked.
Read the documentation for loadView, you are using it incorrectly. You should not call super from loadView and you must set the view property in the view controller. You should not invoke the getter for view [self view] from inside loadView, because the getter calls loadView. You are supposed to create the view in loadView and set the view property.
Something like this:
- (void)loadView {
NSArray *a = [[NSBundle mainBundle] loadNibNamed:@"JCEKKeyboard" owner:self options:nil];
UIView *v = [a objectAtIndex:0];
CGRect frame = [UIScreen mainscreen].applicationFrame;
UIScrollView *s = [[UIScrollView alloc] initWithFrame: frame];
[s setContentSize:CGSizeMake(400, 500)];
[s addSubview:v];
self.view = s;
}
精彩评论