I support portrait only ATM, I get these error when rotating the device:
[__NSCFData setProperRotation]: unrecognized selector sent to instance 0x2dc890
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFData setProperRotation]: unrecognized selector sent to instance 0x2dc890'
This is in iOS5.1. Initially I just left the default portrait clause in, but changed it to:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if (interfaceOrientation == UIInterfaceOrientationPortrait) { // Or whatever orientation it will be presented in.
return YES;
}
return NO;
}
I am using ARC btw.
Hoping that would help stop the crashing. My info.plist has portrait and portrait upside down. There is nothing else I have done thats stock practice except my main view has multiple ViewControllers and its set to:
self.wantsFullScreenLayout=YES;
Any ideas peoples? Thanks in advance.
My project adds the main view from the appdelegate as such:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
mainViewController=[[MainViewController alloc] init];
[self.window addSubview:mainViewController.view];
And I have 2 ViewControllers on that mainViewController and I use a Navigation controller to push several ViewControllers as such:
- (void) loadActionsView {
NSArray* views = [self.navigationController viewControllers];
if ([views containsObject: actionsPanelViewController])
{
[self.navigationController popToViewController:actionsPanelViewController animated:YES];
} else {
[self.navigationController pushViewController:actionsPanelViewController animated:YES];
}
[[StateModel stateModel] setCurrentScreenIndex:0];
}
This is the first view that is called btw.
Update 2 with Solution/problem found:
I was using part of SHK the SHKActivityIndicator, that had a notification that was capturing the screen rotation and its selectors where causing the issue:
[[NSNotificationCenter defaultCenter] addObserver:currentIndicator selector:#selector(setProperRotation) name:UIDeviceOrientationDidChangeNotification object:nil];
It sounds like your ViewController is released and another Object receives setProperRotation message. Check if your ViewController is alive.
mainViewController=[[MainViewController alloc] init];
[self.window addSubview:mainViewController.view];
here is the problem. You adding only the view. ARC thinks that you dont need your MainViewController anymore.
Make MainViewController as a Class variable or
set window.rootViewController
self.window.rootViewController = mainViewController;
The exception shows that you are likely over-releasing an object which is supposed to responds to -setProperRotation. Look for that object and try to understand where you forgot to retain it (for example, track its retains and releases with Object allocation instrument)
Related
I'm trying to update an iOS app written 6 years ago using OpenGL ES and Objective C.
When running the app as it is, I get this error:
4DRoom_v3[2360:42863] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Application windows are expected to have a root view controller at the end of application launch'
From what I have read here I need to set the root view controller.
I add the subview here:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[MeshViewAppDelegate globalVarInit];
//sleep(1);
glView.multipleTouchEnabled = TRUE;
load4Dice();//(str, NEW);
[window addSubview:glView];
//[window makeKeyAndVisible];
glView.animationFrameInterval = 1.0/40;
printf("finish luanching\n");
//[glView startAnimation];
return YES;
}
glView is a subclass of UIView. But I don't see how to implement the solution given since in this case, the view is not a property of a UIViewController.
It isn't clear to me what UIViewController I could set as the root view controller.
Any help would be greatly appreciated.
Create a view controller and add your glview as subview:
UIViewController* vc = [[UIViewController alloc]initWithNibName:nil bundle:nil];
[vc.view addSubview:glview];
window.rootViewController = vc;
I'm working on an iOS 7.1 app on Xcode 5.1.1 (can't be upgraded currently), with ARC and without a StoryBoard, and when I call an empty method in the viewDidLoad method, the app crashes at the end of my custom method. Currently, I'm thinking that it's either my older version of Xcode, or the fact that I'm not using a StoryBoard, but I've simplified the code as much as possible and still cannot find the error. if someone could point out what I'm doing wrong, that would be great, thanks!
The crash just says Thread 1: breakpoint 1.1, crashing when [self.window makeKeyAndVisible] calls [viewController viewDidLoad].
ViewController.h
#interface XYZContactsTableViewController : UITableViewController
#end
ViewController.m:
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self getAddressBook];
}
- (void)getAddressBook {
} // App crashes at line point exactly
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
XYZContactsTableViewController *viewController = [[XYZContactsTableViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = navigationController;
[self.window makeKeyAndVisible];
return YES;
}
Edits:
Also, calling pure C functions in the viewDidLoad method works, so the problem has something to do with the viewController object.
The crash just says Thread 1: breakpoint 1.1
Aha. You are not crashing at all. You are just pausing at a breakpoint. If you don't want to pause, or if breakpoints confuse you, take the breakpoint away or turn breakpoints off. Breakpoints are great, but you clearly don't understand them, so turn them off for now (but do learn to use them eventually, as they are extremely cool!).
why don't you use some already implemented component? :)
Check KBContactsSelection which allows you to search and select multiple contacts and is easily customizable using elegant Builder Pattern.
When my app first loads, I set the rootViewController property of my UIWindow to controllerA.
Sometime during my app, I choose to change the rootViewController to controllerB.
The issue is that sometimes when I do a flip transition in controllerB, I see controllerA's view behind it. For some reason that view isn't getting removed. Whats even more worrying is that after setting the rootViewController to controllerB, controllerA's dealloc method never gets fired.
I've tried removing the subviews of UIWindow manually before switching to controllerB, that solves the issue of seeing controllerA's views in the background but controllerA's dealloc still never gets called. Whats going on here????
Apples docs say:
The root view controller provides the content view of the window. Assigning a view controller to this property (either programmatically or using Interface Builder) installs the view controller’s view as the content view of the window. If the window has an existing view hierarchy, the old views are removed before the new ones are installed.
UPDATE
Here's the code of my AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self showControllerA];
[self.window makeKeyAndVisible];
return YES;
}
- (void)showControllerA
{
ControllerA* a = [ControllerA new];
self.window.rootViewController = a;
}
- (void) showControllerB {
ControllerB* b = [ControllerB new];
self.window.rootViewController = b;
}
It turns out there are two separate issues. 1) I had a retain cycle in Controller A so it was never getting dealloc'd. Secondly, in order to change the root view controller you must remove the windows subviews first (even though the docs suggest otherwise)
The problem could be in your implementation of ControllerA or ControllerB, they may retain 'self' in the code so ARC cant automatically dealloc you ViewController. Can you post you ControllerA and ControllerB implementation.
var loginNavigationController: OnBoardViewController?{
willSet{
if newValue == nil {
loginNavigationController?.view.removeFromSuperview()
}
}
}
loginNavigationController = nil
It's apple's bug, we assume ViewControllerA as the current rootViewController:
// ViewControllerA.m
- (void)buttonClick {
[self dismissViewControllerAnimated:YES completion:^{
// [((AppDelegate *)[[UIApplication sharedApplication] delegate]) resetRoot]; // OK
}];
[((AppDelegate *)[[UIApplication sharedApplication] delegate]) resetRoot]; // ViewControllerA's view will not dealloc
}
// AppDelegate.m
- (void)resetRoot {
ViewControllerB *controller = [[ViewControllerB alloc] init];
self.window.rootViewController = controller;
}
If reset window's rootViewController as this code, the ViewControllerA's view will never dealloc.
An even simpler solution is to set the backgroundColor of your new window to .white or any color. The default is nil, which results in a transparent background. That is why the older window (on top of which the new one is made visible) is being seen through.
I am facing crash with following code. The scenario is
This is my app delegate method in which i load RTC_HomeVC using UINavigationController.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
RTC_HomeVC *obj_RTC_HomeVC=[[RTC_HomeVC alloc]init];
UINavigationController *nav=[[UINavigationController alloc]initWithRootViewController:obj_RTC_HomeVC];
// Override point for customization after application launch.
self.window.rootViewController=nav;
[obj_RTC_HomeVC release];
[nav release];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
Now I want to open UINavigationController inside a parent Navigation controller. So i use a following code. The method -(IBAction)call_SectionFlow is in RTC_HomeVC.
-(IBAction)call_SectionFlow{
RTC_1_StoreDetailsVC *obj_StoreDetailsVC=[[RTC_1_StoreDetailsVC alloc]initWithNibName:#"RTC_1_StoreDetailsVC" bundle:nil];
RTC_3_EnablingWorksVC *obj_EnablingWorksVC = [[RTC_3_EnablingWorksVC alloc]initWithNibName:#"RTC_3_EnablingWorksVC" bundle:nil];
UINavigationController *navController_Sections = [[UINavigationController alloc] init];
NSArray *array_ControllerArray=[[NSArray alloc]initWithObjects:obj_StoreDetailsVC,obj_EnablingWorksVC, nil];
[navController_Sections setViewControllers:array_ControllerArray animated:FALSE]
navController_Sections.view.frame=CGRectMake(14, 40, 996,636 );
[self.view addSubview:[[[navController_Sections viewControllers] objectAtIndex:0] view]];
}
When i called this method application is crashed. This is crash log.
Crash log:
* Terminating app due to uncaught exception 'UIViewControllerHierarchyInconsistency', reason: 'child view controller:< RTC_1_StoreDetailsVC: 0x71f53a0 > should have parent view controller:< RTC_HomeVC: 0x758b310 > but actual parent is:< UINavigationController: 0x71f55d0 >'
* First throw call stack:
(0x1c9c012 0x10d9e7e 0x1c9bdeb 0x6838a 0x68739 0x6f5a3 0x67eed 0x4fc3 0x10ed705 0x24920 0x248b8 0xe5671 0xe5bcf 0xe4d38 0x5433f 0x54552 0x323aa 0x23cf8 0x1bf7df9 0x1bf7ad0 0x1c11bf5 0x1c11962 0x1c42bb6 0x1c41f44 0x1c41e1b 0x1bf67e3 0x1bf6668 0x2165c 0x1f82 0x1c45)
libc++abi.dylib: terminate called throwing an exception
So any one can tell me
What is wrong with this code? And which approach i should follow for resolving this crash ?
How to open another UINavigationController in existing UINavigationController?
Thanks.
Do not add subviews to UIWindow manually. It is not supported (or at least it does not work OK).
Use this method:
[firstNavigationVC presentViewController:secondNavigationVC animated:YES completion:nil];
What is causing crash is, that you are adding obj_StoreDetailsVC to the new navigation controller and then its view to self.view. Once a VC is child of another VC, its view must be descendant of that VC's view. Maybe you can add secondNavigationVC's view to to the view of firstNavigationVC, but that isn't how UIKit is supposed to work. Use the above method.
I have been having some memory management issues and random crashes with my app. I have done a lot of work on it to try to clean up the code generally and have converted the project to ARC.
I now have a clear view on the problem - essentially the app does not release views so as a user moves through the app each view is reloaded and retained until finally the app crashes due to memory issues.
I have a UINavigationController. My app runs only in landscape left orientation. When i use
[window setRootViewController:viewController];
on load and then
[self.window addSubview:[finalViewController view]];
the new view is displayed in portrait - if i rotate it to landscape left with code when i load it in, then all kinds of other random issues come up.
If instead of addSubview i use
[self.viewController.view removeFromSuperview];
[self.window setRootViewController:finalViewController];
viewController = nil;
self.viewController = nil;
window.viewController = nil;
rotation is ok but views are not released and i have a memory issue with the app and it crashes eventually. Any thoughts would be awesome - appreciate i'm probably missing something fairly basic here. Thanks & happy holidays!
How are you loading new views in your app? If you are using a UINavigationController, your AppDelegate should start something like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
RootViewController* rootController = [[RootViewController alloc] init];
UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:rootController];
[self.window setRootViewController:navController];
[self.window makeKeyAndVisible];
return YES;
}
To load another view(say from a button press) you will do something like this from within the root view:
SecondViewController *secondView = [SecondViewController alloc] init];
[self.navigationController pushViewController:secondView animated:YES];
This will make the UINavigationController responsible for memory management of your views.
As for rotation, that is handled by giving each of your ViewControllers this method:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if(interfaceOrientation == UIInterfaceOrientationLandscapeLeft) return YES;
return NO;
}
Aslong as you are using the UINavigationController the way it is meant to be used, you should not have any non-releasing views. You should read into the UINavigationController: http://developer.apple.com/library/ios/#documentation/uikit/reference/UINavigationController_Class/Reference/Reference.html
Another possibility is that the childviews of your view controllers have strong references to their parent view/controller. This will stop a parent viewcontroller from deallocating due to it giving its child a retain count of 1 and the child giving the parent a retain count of 1 as well. Here is a SO post with information on strong & weak references: Objective-C declared #property attributes (nonatomic, copy, strong, weak)