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.
Related
I've created a blank iPhone app project and would like to show a full-screen advertisement during app launch.
I tried to install the ad by following this guideline: https://github.com/mopub/mopub-ios-sdk/wiki/Interstitial-Integration-For-iOS
That's what I've done finally:
Actually all codes are just copied from the previous link.
However, an error shows when app runs:
Application windows are expected to have a root view controller at the end of application launch
I think this error may probably related to the loadView method, because if I remove the loadView method, the error disappeared.
In fact, this error seems common as it can be easily searched on the internet, but I don't know how loadView is related to it, and how can it be solved in my case.
Any solutions? Thanks a lot.
You probably need to do this:
Add
#import "ViewController.h"
to the top of AppDelegate.m
And in AppDelegate.m, your application:didFinishLaunchingWithOptions: method should have some code like this.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// ... Other code
// Override point for customization after application launch.
ViewController *viewController = [[ViewController alloc] init];
self.window.rootViewController = viewController;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
UIViewController *vc = [[UIViewController alloc] init];
[vc.view addSubview:self.tab_controller.view];
[self.window setRootViewController:vc];
OR
UIViewController *vc = [[UIViewController alloc] init];
[vc.view addSubview:yourClass.view];
[self.window setRootViewController:vc];
If you started with an empty template and added a storyboard, you need to do a couple of things:
You need to delete all the lines (except return statement) inside didFinishLaunchingWithOptions
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
return YES;
}
In project settings ->General, select your storyboard as the main interface
Attached snapshot to help you
At the right side check there is one option under attribute inspector which asks to set as "is rootView controller"
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)
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)
I am working in iOS 5,and before loading my application,I want to open a another view controller,where the user should enter some data,for eg.password and when the password matches ,application will be opened,I am not getting how to do this..I tried some code ,which I have written below
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if(somecondition)
{
ViewController *View =[[ViewController alloc]initWithNibName:#"ViewController" bundle:nil];
[_window addSubview:View.view];
}
return YES;
}
But I dont know whether it is a right way,so friends,please help me out..
Regards
Ranjit
You should use
[self.window setRootViewController:yourViewController]
instead of addSubview to your window.
BTW, searching before asking is a good habit. ;)
If you want to show a view like the loginView or loadingView, you can set it as your rootViewController, when did loaded, you can reset your rootViewController.
Note, in your ProjectAppDelegate.m, you can get window
by self.window, and in other child view controller's, you'll need
[[[UIApplication sharedApplication] delegate] window]
to get your main window.
Another simple way to meet your requirement is that you can just present a modalView before showing your app. Dismiss it after done and then start your app.
You can get more suggestion HERE.
BTW, I'm sorry I didn't get your comments' notification when you are write at other users comment area a few days ago. :( You should add # before the user's name when you comment at somewhere else.
You can create some bool variable for checking is this a first start or another. The best place to store this bool is NSUserDefaults. Well, if this is a first start then show your LoginViewController, if not - execute regular code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIViewController *startVC = nil;
if (isFirstLaunch){
startVC = [[[LoginViewController alloc] initWithNibName:#"LoginView" bundle:nil] autorelease];
}
else{
startVC = [[[WorkspaceViewController alloc] initWithNibName:#"WorkspaceView" bundle:nil] autorelease];
}
navController = [[UINavigationController alloc] initWithRootViewController:startVC];
[self.window makeKeyAndVisible];
[self.window addSubview:navController.view];
return YES;
}
When you create a new xcode project using a view based application template, here is the code in the app delegate for the viewController in the "application:didFinishLaunchingWithOptions"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
In Apple's Your First iOS Application Guide
which starts with the window based application template, we need to alloc and init our viewcontroller class and then point the app delegates viewcontroller ivar to that. Then release. See code below:
MyViewController *aViewController = [[MyViewController alloc]
initWithNibName:#"MyViewController" bundle:[NSBundle mainBundle]];
[self setMyViewController:aViewController];
[aViewController release];
I can't find memory allocation or initialization anywhere in the view-based application template. What am I missing?
The initialization is made in the NIB (named in the plist), doing it again in code would be useless, while the second example doesn't create in NIB and, therefore, needs an initialization in code... or maybe I'm missing something.