I have recently started to learn Obj-C and Iphone development basically through Lynda.com iOs SDK essentials course. But it was written for Xcode 3.x and I have 4.0.x installed, so things are different.
Basically, I take example from there and it just doesn't work for me and I can't figure it out being a noob to it.
//basicViewController.h
#import <UIKit/UIKit.h>
#interface basicViewController : UIViewController {
IBOutlet UITextField *txtName;
IBOutlet UILabel *lblMessage;
}
#property (nonatomic, retain) IBOutlet UITextField *txtName;
#property (nonatomic, retain) IBOutlet UILabel *lblMessage;
- (IBAction) doSomething;
#end
And my basicViewController.m
#import "basicViewController.h"
#implementation basicViewController
#synthesize txtName;
#synthesize lblMessage;
- (IBAction) doSomething
{
NSString *msg = [[NSString alloc] initWithFormat:#"Hello, %#",txtName.text];
[lblMessage setText:msg];
[msg release];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
I haven't changed basicAppDelegate.h and .m from what they were created like. I think I will post them anyway.
//
// basicAppDelegate.h
#import <UIKit/UIKit.h>
#class basicViewController;
#interface basicAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
basicViewController *viewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet basicViewController *viewController;
#end
//
// basicAppDelegate.m
#import "basicAppDelegate.h"
#import "basicViewController.h"
#implementation basicAppDelegate
#synthesize window;
#synthesize viewController;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after app launch
[window addSubview:viewController.view];
[window makeKeyAndVisible];
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
#end
And here's my main.m:
//
// main.m
#import <UIKit/UIKit.h>
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
Also, on the Interface Builder window I have linked through File's Owner: label to lblMessage, TextField to txtName and doSomething to Button.
Now, the problem is: actually, the thing kinda works, only if I use the popup keyboard, not my physical one. And only if I type less than 3-4-5 symbols(differs sometimes).
If I use my keyboard, not the popping one - it gives me Thread 1 received signal EXC_BAD_ACCESS.
Same if I type too many symbols.
And I don't see much in All Output - just some usual stuff, the only suspicious line is:
warning:unable to compile regular expression "dyld"
Current language: auto; currently objective-c
(gdb)
So, guys, any kind help is appreciated.
First, there didn't change something since Xcode 3 except the interface.
Try to set a breakpoint and look where you app is crashing...
Try to delete the IBOutlets and create it new...
Try to create a new app...
If all not works, take your Mac and throw it outside a window, bring it back to Apple. (or install Xcode again --> much cheaper..)
I had the exact same problem and spent AGES looking for the solution. I found out how to make it work and I've made a tutorial on how to make the Hello, Name application on XCode. Take a look and see if it helps. I think if you follow the steps one by one you should have your app running in no time.
http://techtalktone.wordpress.com/2011/11/26/hello-world/
Hope this helps ;)
Related
I'm new to creating iPhone Applications and have just started with Xcode and am getting the following errors; I have used this code previously on both the simulator & an iPod touch and it worked fine for both but for some reason lately it will not allow me to go from one page to another without giving me the "SIGABRT" error.
Basically in my application I need to go from one page to another several times but it will not work....can anyone help with this please?
This is the code it seems unhappy with (it complies & builds successfully):
1 #import <UIKit/UIKit.h>
2
3 int main(int argc, char *argv[])
4 {
5 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
6 int retVal = UIApplicationMain(argc, argv, nil, nil);
7 [pool release];
8 return retVal;
9 }
It stops on the int retVal line (6th line).
When debugging it gave the error:
2011-09-09 15:33:59.029 TruckFile[1072:b603] * Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[< UIApplication 0x6044600> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key window.'
Can anyone help me with this please?
Thank you in advance!
========================================
Code files:
========================================
Main page (.h)
#import <UIKit/UIKit.h>
#import "ViewTwoController.h"
#import "TruckFileAppDelegate.h"
#interface TruckFileAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
ViewTwoController *viewTwoContoller;
UINavigationController *navigationController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
#property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
#property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
#property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
#property (nonatomic, retain) ViewTwoController *viewTwoController;
-(IBAction)switchPage:(id)sender;
#end
================================================
Main page (.m)
#import "TruckFileAppDelegate.h"
#import "ViewTwoController.h"
#implementation TruckFileAppDelegate
#synthesize window;
#synthesize navigationController;
#synthesize managedObjectContext = __managedObjectContext;
#synthesize managedObjectModel = __managedObjectModel;
#synthesize persistentStoreCoordinator = __persistentStoreCoordinator;
#synthesize viewTwoController;
-(IBAction)switchPage:(id)sender
{
if(self.viewTwoController == nil)
{
ViewTwoController *viewTwo = [[ViewTwoController alloc]
initWithNibName:#"ViewTwoController" bundle:[NSBundle mainBundle]];
self.viewTwoController = viewTwo;
[viewTwo release];
}
[self.navigationController pushViewController:self.viewTwoController animated:YES];
}
- (void)dealloc {
[navigationController release];
[window release];
[super dealloc];
}
#end
====================================
Page 2 (.h)
#import <UIKit/UIKit.h>
#interface ViewTwoController : UIViewController {
}
#end
=====================================
Page 2 (.m)
#import "ViewTwoController.h"
#implementation ViewTwoController
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
- (void)dealloc {
[super dealloc];
}
#end
The mainWindow.xib is trying to connect it's UIWindow instance with your UIApplicationDelegate's and it can't find it (that's why it complains it can't set the value for an UNDEFINED key).
Check your UIApplicationDelegate class has a UIWindow iVar, a property in its .h and it's correctly synthesized in its .m.
EDIT
Who's calling the method switchPage: on UIApplication? If you are, you're calling it on the wrong object. Instead of doing
[[UIApplication sharedApplication] switchPage:xxx];
You should do:
[[[UIApplication sharedApplication] delegate] switchPage:xxx];
Since the method switchPage: is defined in the UIApplicationDelegate class.
Your code fails at
[UIApplication switchPage:]:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIApplication switchPage:]: unrecognized selector sent to instance 0x600beb0'
This means that in your switchPage method, you are giving an action to an unknown identifier, maybe check the object identifier name, and check if you have initialized it in your .h file.
Heads Up: I'm not too comfortable with Objective C to know exactly what I'm talking about..
Here's my life story:
My app basically consists of 3 views: main, facebook, and twitter.. No problems with the twitter, no problems switching back and forth between views until... bum bum bum.. I started using the Facebook API in guidance from this site: http://www.mobisoftinfotech.com/blog/iphone/iphone-fbconnect-facebook-connect-tutorial/
Now I can connect to FB and use their API and post without any problem, but when I switch back from the Facebook View on my app to the main view, it switches and then immediately crashes..
FacebookViewController.m
#import "FacebookViewController.h"
#import "Crush_LoveAppDelegate.h"
#define _APP_KEY #"43e37a535cc09c2013bd76fde78dfcc7"
#define _SECRET_KEY #"cc14801521a0c4d1dc31b7cacb891072"
#implementation FacebookViewController
#synthesize facebookFeed;
#synthesize delegate;
#synthesize loginButton;
#synthesize facebookAlert;
#synthesize usersession;
#synthesize username;
#synthesize post;
- (void)viewDidLoad {
Crush_LoveAppDelegate *appDelegate =
(Crush_LoveAppDelegate *) [[UIApplication
sharedApplication]delegate];
if (appDelegate._session == nil){
appDelegate._session = [FBSession sessionForApplication:_APP_KEY secret:_SECRET_KEY delegate:self];
}
if(self.loginButton == NULL)
self.loginButton = [[[FBLoginButton alloc] init] autorelease];
loginButton.frame = CGRectMake(110, 200, 100, 50);
[self.view addSubview:loginButton];
[super viewDidLoad];
self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor];
}
- (IBAction)done:(id)sender {
[self.delegate facebookViewControllerDidFinish:self];
}
FacebookViewController.h
#import <UIKit/UIKit.h>
#import "FBConnect/FBConnect.h"
#import "FBConnect/FBSession.h"
#import "FBConnect/FBRequest.h"
#import "FBConnect/FBStreamDialog.h"
#protocol FacebookViewControllerDelegate;
#interface FacebookViewController : UIViewController <UIApplicationDelegate, FBSessionDelegate, FBRequestDelegate>{
IBOutlet UIWebView *facebookFeed;
id <FacebookViewControllerDelegate> delegate;
FBLoginButton *loginButton;
UIAlertView *facebookAlert;
FBSession *usersession;
NSString *username;
BOOL post;
}
#property(nonatomic,retain) FBLoginButton *loginButton;
#property(nonatomic,retain) UIAlertView *facebookAlert;
#property(nonatomic,retain) FBSession *usersession;
#property(nonatomic,retain) NSString *username;
#property(nonatomic,assign) BOOL post;
#property (nonatomic, assign) id <FacebookViewControllerDelegate> delegate;
#property (nonatomic, retain) IBOutlet UIWebView *facebookFeed;
- (IBAction)done:(id)sender;
#end
#protocol FacebookViewControllerDelegate
- (void)facebookViewControllerDidFinish:(FacebookViewController *)controller;
- (BOOL)textFieldShouldReturn:(UITextField *)textField;
-(void)getFacebookName;
-(void)postToWall;
#end
I chopped some of the .m off of the post to save space, but you get the idea.. I've narrowed it down and it seems like the problem is caused during this line in .m
appDelegate._session = [FBSession sessionForApplication:_APP_KEY secret:_SECRET_KEY delegate:self];
I've been trying to debug it myself for a few hours and I don't know enough on my own to diagnose it myself..
Any thoughts?
Im not sure why your app is crashing, but thought I'd mention that there are a few really good Apple WWDC videos about bug checking and crashing in XCode. In particular, "Debugging with Xcode 4 and LLDB" and "Understanding Crash Reports on iPhone OS", both from the WWDC 2010 videos. I believe you need a developer login to access these videos however but certainly worth a look if you're interested in learning more about debugging.
Okay, for anyone else who had this issue, here's what I did..
FacebookViewController.m File
- (void)dealloc {
[username release];
[usersession release];
[loginButton release];
[super dealloc];
}
I commented out the [loginButton release]; line and it worked oddly enough.. I don't know if this will give me serious problems down the road, but it works for now..
I have started learning iphone apps development. However when I build and run the project, the simulator opens with new app icon. When I click on the new app icon ...nothing happens.
-->> simulator just sits there and doesn't load the app
Any help will be appreciated.
Marty
Actually it is not my code. I got it from the book I am studying from. Here it is:-
#import "basicViewController.h"
#implementation basicViewController
#synthesize txtName;
#synthesize lblMessage;
- (IBAction) doSomething;
{
NSString *msg =[[NSString alloc] initWithFormat:#"Hello, %#", txtName.text];
[lblMessage setText:msg];
[msg release];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
//------------------------
#import <UIKit/UIKit.h>
#interface basicViewController : UIViewController {
IBOutlet UITextField *txtName;
IBOutlet UILabel *lblMessage;
}
#property (nonatomic, retain) IBOutlet UITextField *txtName;
#property (nonatomic, retain) IBOutlet UILabel *lblMessage;
- (IBAction) doSomething;
#end
I have the following code in my AppDelegate.h file:
#class mainViewController;
#class AboutViewController;
#interface iSearchAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
mainViewController *viewController;
AboutViewController *aboutController;
UINavigationController *nav;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet mainViewController *viewController;
#property (nonatomic, retain) IBOutlet AboutViewController *aboutController;
#property (nonatomic, retain) IBOutlet UINavigationController *nav;
[...IBActions declared here...]
#end
Then, in my .m file:
#implementation iSearchAppDelegate
#synthesize window;
#synthesize viewController, aboutController, settingsData, nav, engines;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[window addSubview:nav.view];
[window addSubview:aboutController.view];
[window addSubview:viewController.view];
[window makeKeyAndVisible];
}
-(IBAction)switchToHome{
[window bringSubviewToFront:viewController.view];
}
-(IBAction)switchToSettings{
[window bringSubviewToFront:nav.view];
}
-(IBAction)switchToAbout{
[window bringSubviewToFront:aboutController.view];
}
- (void)dealloc {
[viewController release];
[aboutController release];
[nav release];
[window release];
[super dealloc];
}
#end
Somehow, when I run the app, the main view presents itself fine... however, when I try to execute the actions to switch views, the app crashes with an EXC_BAD_ACCESS.
So, I think it has something to do with memory management, but I'm not quite sure.
Thanks for any help in advance.
Link to screenshots of code is here: link...
SOLVED: I fixed the issue by taking out the IBActions and making them into regular methods... apparently, XCode doesn't like it when you put IBActions in an AppDelegate.
... message sent to deallocated instance ...
If it is memory management, my first step would be to enable NSZombie and discover what was being messaged after being dealloc'ed. Two obvious things I can think of:
Uninitialised property/variable.
De-allocated (non-retained) property
Have your controls in interface builder been connected to the IBActions?
Somewhere in your code, you are invoking [iSearchAppDelegate performSelector:withObject:withObject:]. You haven't shown that code here but that's likely where the problem is.
I have an iPhone application that loads succesive views in a framework based on the one explained in this link (basically a main ViewController that loads/removes additional views with a displayView method). In my application I am using NIBs (the example link uses coded views) though so each of my ViewControllers has its accompanying nib.
Debugging in Instruments shows no leaks but if I enter/leave a section (ViewController with its View.xib), the nib remains in memory so after a few in/outs memory starts to accumulate.
I know the nib is not being unloaded because one is almost programmatically created (no stuff in IB) while another does have images and buttons created in IB. The large one is loaded first and the small one loads next. You would expect a reduction in allocation in Instruments.
How can I prevent this?
My structure is as follows, with a few comments below:
`MyAppDelegate.h`
#import <UIKit/UIKit.h>
#class RootViewController;
#interface MyAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
RootViewController *viewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet RootViewController *viewController;
-(void) displayView:(int)intNewView;
#end
`MyAppDelegate.m`
#import "MyAppDelegate.h"
#import "RootViewController.h"
#implementation MyAppDelegate
#synthesize window;
#synthesize viewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[window addSubview:viewController.view];
[window makeKeyAndVisible];
return YES;
}
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
}
-(void) displayView:(int)intNewView {
[viewController displayView:intNewView];
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
#end
This controller handles subview load/removes:
`RootViewController.h`
#import <UIKit/UIKit.h>
#interface RootViewController : UIViewController {
}
- (void) displayView:(int)intNewView;
#end
`RootViewController.m`
#import "RootViewController.h"
#import "ViewController.h"
#implementation RootViewController
UIViewController *currentView;
- (void) displayView:(int)intNewView {
NSLog(#"%i", intNewView);
[currentView.view removeFromSuperview];
[currentView release];
switch (intNewView) {
case 1:
currentView = [[ViewController alloc] initWithNibName:#"View" bundle:nil];
break;
}
[self.view addSubview:currentView.view];
}
- (void)viewDidLoad {
currentView = [[ViewController alloc]
initWithNibName:#"View" bundle:nil];
[self.view addSubview:currentView.view];
[super viewDidLoad];
}
- (void)dealloc {
[currentView release];
[super dealloc];
}
#end
There would be as many case as "detail" ViewControllers I have (right now I have 3 case but this will grow to 10 or more). The purpose of this structure is to easily move from one "section" of the application to another (NavBar controller or TabBar controller do not suit my specific needs).
`ViewController.h`
// Generic View Controller Example
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController {
UIImageView *_image1;
UIImageView *_image2;
NSTimer *_theTimer;
}
#property (nonatomic, retain) IBOutlet UIImageView *image1;
#property (nonatomic, retain) IBOutlet UIImageView *image2;
#property (nonatomic, retain) NSTimer *theTimer;
#end
`ViewController.m`
#import "ViewController.h"
#import "MyAppDelegate.h"
#synthesize image1 = _image1, image2 = _image2, theTimer = _theTimer;
- (void)loadMenu {
[self.theTimer invalidate];
self.theTimer = nil;
MyAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate displayView:2];
}
-(void)setView:(UIView*)aView {
if (!aView){
self.image1 = nil;
self.image2 = nil;
}
[super setView:aView];
}
- (void)viewDidLoad {
//some code
[super viewDidLoad];
}
- (void)viewDidUnload {
self.image1 = nil;
self.image2 = nil;
}
- (void)dealloc {
NSLog(#"dealloc called");
[self.theTimer invalidate];
[self.theTimer release];
[self.image1 release];
[self.image2 release];
[super dealloc];
}
Notice the NSLog in dealloc. This is being called (I can see it in the console) but the memory needed for the nib is not freed (Instruments shows an increase in memory allocation when leaving a section, because a new nib is loaded).
Any help will be greatly appreciated. I have tried a million different things and I cannot get the nibs to unload.
After a million different tries I finally ran into this forum.
It states:
Apparently images assigned in IB are loaded into image views using imageNamed. imageNamed caches the images in a way that makes them unloadable. You could load the images in viewDidLoad with initWithContentsOfFile and then assign them to the views.
Somewhere else I had read that imageNamed is the devil so I'd rather not have my images load that way.
(BTW this is iPhone OS 3.1 I'm using)
What I ended up is leaving the UIImageView intact in IB but with an empty .image value. The modified code is something like:
- (void)viewDidLoad {
NSString *path = [NSString stringWithFormat:#"%#/%#", [[NSBundle mainBundle] resourcePath], #"myImageThatBeforeWasAValueinIB.jpg"];
UIImage *image = [UIImage imageWithContentsOfFile:path];
outlet.image = image;
// do the rest of my stuff as it was
[super viewDidLoad];
}
- (void)dealloc {
outlet.image = nil;
[outlet release], outlet = nil;
[super dealloc];
}
And now everything works like a charm! Memory is recovered when I unload a nib and when I get memory warnings.
So pretty much if you have IBOutlets for UIImageViews and memory is a concern (it always is I guess), you can design all you want in IB and when the time comes to connect them to outlets, remove the image reference in IB and create it from code. IB is really good for laying out your app. It would suck to have to do all that thing by code, but I also found this nice utility that converts nibs to objective c code although I haven't tested it yet.
Did you try setting your outlet variables to nil in dealloc?
You are correctly implementing the setView method, but you are setting your outlet variables to nil in the viewDidUnload method instead of dealloc. As discussed here, you should implement dealloc as follows:
- (void)setView:(UIView *)aView {
if (!aView) { // view is being set to nil
// set outlets to nil, e.g.
self.anOutlet = nil;
}
// Invoke super's implementation last
[super setView:aView];
}
- (void)dealloc {
// release outlets and set outlet variables to nil
[anOutlet release], anOutlet = nil;
[super dealloc];
}
EDIT: if the outlets are UIImageViews, then it may be the case that you need to do
anOutlet.image = nil;
because setting the UIImage’s instance image property should increase the retain count of the UIImage’s instance by 1.