Objective-c and Xcode strange behavior - objective-c

In xcode 4.3.1, target iPad 5.1 simulator
create a single view app
use ARC, don't use Storyboard
in ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
{
NSObject *anObject;
NSObject *anotherObject;
}
-(void) makeObjects;
#end
in ViewController.m add
-(void) makeObjects{
anObject = [[NSObject alloc] init];
anotherObject = [[NSObject alloc] init];
int a = 1;
}
in AppDelegate.m add a line
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.viewController makeObjects]; // ADD THIS LINE <--------
[self.window makeKeyAndVisible];
return YES;
}
in ViewController.m, set a breakpoint at
anObject = [[NSObject alloc] init];
run
step over breakpoint
anObject = 0x00000000, anotherObject is set!

Are you using the LLDB debugger? Currently it doesn't give you correct values on iVars in the simulator. Switch back to GDB and you'll find the correct values reported. I discovered this behavior here: UIViewController subclass can't assign instance variable.
And yes, I reported a bug. I got a response back from Apple stating it is a known issue.

Related

receiver type 'AppDelegate' for instance message does not declare a method with selector ERROR

Can't seem to nail this issue here. Any idea what needs to be changed? I'm using Xcode 4.2.
Error: AppDelegate.m:23:6: error: receiver type 'AppDelegate' for instance message does not declare a method with selector 'setupHUD' [4]
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
LoginViewController *loginVC = [[LoginViewController alloc] init];
UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:loginVC];
navCon.navigationBarHidden = YES;
self.window.rootViewController = navCon;
[self setupHUD];
[self.window makeKeyAndVisible];
return YES;
}
- (void) setupHUD
{
//setup progress hud
self.HUD = [[MBProgressHUD alloc] initWithFrame:self.window.bounds];
[self.window addSubview:self.HUD];
self.HUD.dimBackground = YES;
self.HUD.minSize = CGSizeMake(150.f, 150.f);
self.HUD.delegate = self;
self.HUD.isCancelButtonAdded = YES;
self.HUD.labelText = #"Loading";
}
Prior to Xcode 4.3, you need to forward declare methods called within the same #implementation block, so make sure to add the declaration of setupHUD to either the class extension (the list of declarations inside AppDelegate.m that starts with #interface AppDelegate ()), or the #interface block in AppDelegate.h.
For example, in AppDelegate.m:
#interface AppDelegate ()
// Other declarations...
- (void)setupHUD;
#end
Or in AppDelegate.h:
#interface AppDelegate : NSObject <UIApplicationDelegate>
// Other declarations
- (void)setupHUD;
#end

Add a UITabBarController to a UIViewController (Xcode 4.6)

I am studying Objective-C and I started to create an App while I am learning it.
I have created a "Single View Application" with two "View Controllers" called "ViewController" and "secondViewController", after that I thought to add an "UITabBarController", so following a tutorial I used the following code in the AppDelegate.m
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self customizeInterface];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UITabBarController *tabController = [[UITabBarController alloc] init];
UIViewController *viewController1 = [[UIViewController alloc] init];
UITabBarItem *tab1 = [[UITabBarItem alloc] initWithTitle:#"Artists" image:[UIImage imageNamed:#"artist-tab.png"] tag:1];
[viewController1 setTabBarItem:tab1];
UIViewController *viewController2 = [[UIViewController alloc] init];
UITabBarItem *tab2 = [[UITabBarItem alloc] initWithTitle:#"Music" image:[UIImage imageNamed:#"music-tab.png"] tag:2];
[viewController2 setTabBarItem:tab2];
tabController.viewControllers = [NSArray arrayWithObjects:viewController1,
viewController2, nil];
self.window.rootViewController = tabController;
[self.window makeKeyAndVisible];
// Override point for customization after application launch.
return YES;
}
Here is the ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
If I run the application, the tab bar is working but I have a blank screen and not the ViewController I have created.
Just because I am a noob, could you please tell me how to link or show the view controllers respectively in each tab?
Please be so kind to say everything also the obvious things.
Thank you in advance
Since you are beginner I would highly suggest you to use storyboards, that will help to manage the interface much more easier because you will not have to code almost anything.
http://www.raywenderlich.com/5138/beginning-storyboards-in-ios-5-part-1
I am just guessing but your problem might be that you directly init your view controller , you should call initWithNibName: method in your didFinishLaunchingWithOptions. The initWithNibName: is something that you call when you create a controller instance from a nib file.
So basically initWithNibName: is called when the NIB is loaded and instantiated.
I dont know your ViewContoller class names but you should change your view controllers init methods
in your app delegate.m
#import "ViewController.h"
#import "secondViewController.h"
UIViewController *viewController1 = [[ViewController alloc] initWithNibName:#"ViewController" bundle:[NSBundle mainBundle]]; // make sure on interface builder hat you Nib name is ViewController
UIViewController *viewController2 = [[secondViewController alloc] initWithNibName:#"secondViewController" bundle:[NSBundle mainBundle]];// make sure on interface builder hat you Nib name is secondViewController
and please use Upper Case Chars and detailed names for class name secondViewController is not good programming practice
The tabbar controller shows the views, you created in your code. That's the expected behaviour, since you are creating completely new views.
If you created "ViewController" and "secondViewController" in Interface Builder, then you'll have to load the nibs - instead of creating new views - and tell the tabbar controller to use these.
Basically you'll have to change your lines:
UIViewController *viewController1 = [[UIViewController alloc] init];
to something like
UIViewController *viewController1 = [[UIViewController alloc] initWithNibName:#"view1" bundle:nil];
Please see initWithNibName:bundle: for the details.

Application windows are expected to have a root view controller at the end of application launch error

I keep getting this error, and I cannot figure out why. Everything was working fine, and all of the sudden I got this error. I had not changed the code, and I set the rootViewController in the delegate, so I don't see why I am getting this error. Here is the code from my appDelegate.m file.
#import "WhereAmIAppDelegate.h"
#import "WhereAmIViewController.h"
#implementation WhereAmIAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
WhereAmIViewController *wvc = [[WhereAmIViewController alloc] initWithNibName:#"WhereAmIViewController" bundle:nil];
[[self window]setRootViewController:wvc];
[self.window makeKeyAndVisible];
return YES;
}
I clearly set the rootViewController, so I don't know why this is happening.

No visible interface for #LWWFirstController declares the selector initWithStyle

I am getting the error "No visible interface for #LWWFirstController declares the selector initWithStyle". I have written similar code for setting up my Navigation Controller and it worked fine, but I can't seem to find what is causing this error. I have looked on StackOverFlow for similar issues but none fit, I'm using the correct method for it. Does anyone have in clue? Here is my code below.
#import "LWWAppDelegate.h"
#import "LWWFirstLevelController.h"
#implementation LWWAppDelegate
#synthesize window = _window;
#synthesize navController;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
LWWFirstLevelController *first = [[LWWFirstLevelController alloc] initWithStyle:UITableViewStylePlain];
self.navController = [[UINavigationController alloc]
initWithRootViewController:first];
[self.window addSubview:navController.view];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
It basically says you didn't implement initWithStyle method in your LWWFirstLevelController.
Are you sure it is a subclass of UITableViewController?

Can you use a singleton in a view controller in a tab bar controller just as you would anywhere?

Clarification: The view controller with singletons described below works fine by itself. When embedded into a UITabBarController however, it doesn't work.
Original Title: NSUnknownKeyException: Probably not the nib, could it be the singletons?
Here's yet another one of those "NSUnknownKeyException... this class is not key value coding-compliant for the key" questions which are abundant here. I've been through a lot of them! Here's the full complaint:
NSUnknownKeyException', reason: '[<UIProxyObject 0x683dfe0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key button1.'
It seems these exceptions always come down to problems with the nib having left over variables that were changed elsewhere and did not get cleaned out. So I've worked through all my nib, disconnecting, and re-connecting, checking to no avail. I then deleted the nib and rebuilt it from zero and I have still have the same problem :-( So I turn to the hive mind of SO once again.
Through a series of NSLogs and other tricks I know the problem is with GameViewController (if I get rid of it and replace it with an empty controller the app works fine). Here is the relevant part of GameViewController:
#interface GameViewController : UIViewController <UIAlertViewDelegate>
#end
#implementation GameViewController
- (id) init {
NSLog(#" GVC initializing");
self = [super initWithNibName:#"GameViewController"
bundle:nil];
if (self) {
UITabBarItem *tbi = [self tabBarItem];
[tbi setTitle:#"Play Game"];
}
return self;
}
- (id) initWithNibName:(NSString *)nibName bundle:(NSBundle *)Bundle {
return [self init];
}
- (void)loadView {
[super loadView];
NSLog(#"loadView is starting");
// Set up display of button and label singletons
NSMutableArray *keyArray;
NSMutableArray *valueArray;
keyArray = [NSMutableArray arrayWithObjects:#"answerButtons", #"clueLabels", #"keyPad", nil];
valueArray = [NSMutableArray arrayWithObjects: [AnswerButtons answerButtons], [ClueLabels clueLabels], [KeyPad keyPad], nil];
NSMutableDictionary *externals = [NSMutableDictionary dictionaryWithObjects:valueArray
forKeys:keyArray];
// Fire the button and label singletons
[[AnswerButtons answerButtons] answerButtonsDidLoad];
[[ClueLabels clueLabels] clueLabelsDidLoad];
[[KeyPad keyPad] keyPadDidLoad];
// Set up nibOptions and link to externals
NSDictionary *nibOptions = [NSDictionary dictionaryWithObject:externals
forKey:UINibExternalObjects];
[self.nibBundle loadNibNamed:self.nibName owner:self options:nibOptions];
NSLog(#"loadView is done");
}
#end
Here is the relevant part of my app delegate:
#implementation AppDelegate
#synthesize window = _window;
#synthesize tbc = _tbc;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSLog(#"dFLWO starting");
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UITabBarController *tbc = [[UITabBarController alloc] init];
SettingsViewController *settingsVC = [[SettingsViewController alloc] init];
GameViewController *gameVC = [[GameViewController alloc] init];
// UIViewController *temp = [[UIViewController alloc] init]; // works fine
NSLog(#"dFLWO: both VC's inited");
[tbc setViewControllers:[NSArray arrayWithObjects:gameVC, settingsVC, nil]];
// [tbc setViewControllers:[NSArray arrayWithObjects: temp, settingsVC, nil]]; // works fine
NSLog(#"dFLWO: VC's set");
[[self window] setRootViewController:tbc];
[self.window makeKeyAndVisible];
NSLog(#"TabBarController now active");
return YES;
}
Sorry. That's long. I've gone as far as I can with this being a nib problem. Perhaps it is a problem with those singletons I need to launch? There was a previous version of this project without the tab bar controller in which these singletons (and others not shown) worked just fine.
Suggestions appreciated!