PDA

View Full Version : iPhone app crashing




Duke Leto
Mar 28, 2008, 06:41 PM
Before you tell me that I have not enough experience to be programming, know that I have learned.

I made a little iPhone application that goes from one tableview to another using view controllers. When I attempt to go back, it crashes.

What have I done?



Cromulent
Mar 28, 2008, 06:45 PM
Before you tell me that I have not enough experience to be programming, know that I have learned.

I doubt anyone would tell you that :). We all need to start somewhere.

I made a little iPhone application that goes from one tableview to another using view controllers. When I attempt to go back, it crashes.

What have I done?

Questions like this are impossible to answer without more information in the form of source code I am afraid.

Duke Leto
Mar 28, 2008, 06:47 PM
I can send in some code if it helps :)

What I need to know before I do this is where the problem is likely to be: in the ViewController that cannot go back, or the original ViewController?

Cromulent
Mar 28, 2008, 06:48 PM
I can send in some code if it helps :)

What I need to know before I do this is where the problem is likely to be: in the ViewController that cannot go back, or the original ViewController?

As I said it is impossible to answer without seeing your source code. You could have made a mistake anywhere. Without seeing any code, any answer would just be a guess.

Duke Leto
Mar 28, 2008, 07:22 PM
I am going to try to fix it on my own. The thing is, I had it working, then I accidentally pressed undo and it started crashing. GAH I hate this.

cmaier
Mar 28, 2008, 11:49 PM
what does the console say?

Duke Leto
Mar 29, 2008, 08:17 AM
This is what it says

Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000002, 0x0000000000000000
Crashed Thread: 0

Application Specific Information:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSFastEnumerationEnumerator setAlpha:]: unrecognized selector sent to instance 0x1297420'

Duke Leto
Mar 29, 2008, 08:44 AM
What you have all been waiting for *drumroll*


@implementation UserNameViewController

@synthesize detailItem;
@synthesize tableView;

- (id)init
{
if (self = [super init]) {
self.title = @"Accounts";

}
return self;
}

- (void)loadView
{
tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStylePlain];
tableView.delegate = self;
tableView.dataSource = self;
tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;

self.view = tableView;
}

- (void)dealloc
{
tableView.dataSource = nil;
tableView.delegate = nil;
[passwordViewController release];
[tableView release];
[super dealloc];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[detailItem objectForKey:@"accounts"] count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath withAvailableCell:(UITableViewCell *)availableCell {

UISimpleTableViewCell *cell = nil;
if (availableCell != nil) {
cell = (UISimpleTableViewCell *)availableCell;
} else {
cell = [[[UISimpleTableViewCell alloc] init] autorelease];
}

// Set the value in the cell
NSArray *usernames = (NSArray *)[detailItem objectForKey:@"accounts"];
NSDictionary *account = (NSDictionary *)[usernames objectAtIndex:indexPath.row];
cell.text = [account objectForKey:@"username"];
return cell;
}

- (void)tableView:(UITableView *)tableView selectionDidChangeToIndexPath:(NSIndexPath *)newIndexPath fromIndexPath:(NSIndexPath *)oldIndexPath {
if (passwordViewController == nil) {
passwordViewController = [[PasswordViewController alloc] init];
}
// Set the detail controller's inspected item to the currently-selected item
passwordViewController.detailItem = [[detailItem objectForKey:@"accounts"] objectAtIndex:newIndexPath.row];
[[self navigationController] pushViewController:passwordViewController animated:YES];
}

@end

Yes I know, a lot of the code looks familiar if you have looked at the SimpleDrillDown source code. :o
:apple:

Duke Leto
Mar 29, 2008, 09:10 AM
What about this code:

#import "MasterViewController.h"
#import "UntitledAppDelegate.h"
#import "UserNameViewController.h"

@implementation MasterViewController

@synthesize appController;
@synthesize tableView;

- (id)init
{
if (self = [super init]) {
self.title = @"Categories";
}
return self;
}

- (void) inspectAction:(id) sender
{
}

- (void)loadView {
UIButton *inspectButton = [UIButton buttonWithType:UIButtonTypeNavigation];
[inspectButton setTitle:@"A Button" forStates:UIControlStateNormal];
[inspectButton addTarget:self action:@selector(inspectAction:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.customRightView = inspectButton;
[inspectButton release];

tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStylePlain];
tableView.delegate = self;
tableView.dataSource = self;
tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
self.view = tableView;
}


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}

- (void)dealloc
{

tableView.dataSource = nil;
tableView.delegate = nil;
[tableView release];
[userNameViewController release];
[super dealloc];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [appController.masterList count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath withAvailableCell:(UITableViewCell *)availableCell
{
UISimpleTableViewCell *cell = nil;
if (availableCell != nil) {
// Use the existing cell if it's there
cell = (UISimpleTableViewCell *)availableCell;
} else {
cell = [[[UISimpleTableViewCell alloc] initWithFrame:CGRectZero] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}

// Get the object to display and set the value in the cell
NSDictionary *itemAtIndex = (NSDictionary *)[appController.masterList objectAtIndex:indexPath.row];
cell.text = [itemAtIndex objectForKey:@"title"];
return cell;
}


- (void)tableView:(UITableView *)tableView selectionDidChangeToIndexPath:(NSIndexPath *)newIndexPath fromIndexPath:(NSIndexPath *)oldIndexPath {

// Create the detail view lazily
if (userNameViewController == nil) {
userNameViewController = [[UserNameViewController alloc] init];
}
// Set the detail controller's inspected item to the currently-selected item
userNameViewController.detailItem = [appController.masterList objectAtIndex:newIndexPath.row];
[[self navigationController] pushViewController:userNameViewController animated:YES];
}
@end

Yes there is a button called "A Button" that does nothing. I was just testing out navigation Items.

Duke Leto
Mar 29, 2008, 10:03 AM
Thank you so much! It works.

That taught me something about auto releasing variables :)

*takes snapshot*

spstanley
May 26, 2008, 12:06 PM
May I ask, what works? I might be having a similar problem, but I don't see the post you seem to be responding to.

tacoman667
May 26, 2008, 01:34 PM
The OP was probably releasing property objects. If you are using properties and then you release them before dealloc() then it makes the object invalid and therefor you get this error.

spstanley
May 26, 2008, 10:50 PM
The OP was probably releasing property objects. If you are using properties and then you release them before dealloc() then it makes the object invalid and therefor you get this error.

My problem is probably different, then. I create a navigation controller in my applicationDidFinishLaunching, setting the root view controller to my top view controller, which I initialize from a NIB. My top view controller has a butten that, when pressed, uses pushViewController to push another view controller onto the navigation controller's stack. This other view controller is also initialized from a (different) NIB.

When I touch the back button from the other view controller, my application crashes. This is the last I see in the debugger:


#0 0x9302c6e8 in objc_msgSend
#1 0x30b863cb in -[UIViewController view]
#2 0x30b8b436 in -[UINavigationController _startTransition:fromViewController:toViewController:]
#3 0x30b8bbd3 in -[UINavigationController _popViewControllerWithTransition:allowPoppingLast:]
#4 0x30b8ba87 in -[UINavigationController popViewControllerAnimated:]
#5 0x30b8c880 in -[UINavigationController navigationBar:shouldPopItem:]
#6 0x30b48a22 in -[UINavigationBar popNavigationItemAnimated:]
#7 0x30b4a251 in -[UINavigationBar _handleMouseUpAtPoint:]
#8 0x30b2efbe in -[UIWindow sendEvent:]
#9 0x30b1ec95 in -[UIApplication sendEvent:]
#10 0x30b1e5c0 in _UIApplicationHandleEvent
#11 0x3172d6a2 in SendEvent
#12 0x3172f9ae in PurpleEventTimerCallBack
#13 0x9678b62e in CFRunLoopRunSpecific
#14 0x9678bd18 in CFRunLoopRunInMode
#15 0x3172de5e in GSEventRunModal
#16 0x3172df23 in GSEventRun
#17 0x30b17482 in -[UIApplication _run]
#18 0x30b21c86 in UIApplicationMain
#19 0x000021c0 in main at main.m:13

Duke Leto
May 27, 2008, 09:30 AM
I do not know where the post I was responding to went .. but whoever it was told me that when I created the button object [UIButton buttonWithType:], it was autoreleased. When I released it, it crashed. That was SDK version 1, this is 5, so things are different. However, the idea is the same: never release variables twice.

tacoman667
May 27, 2008, 09:40 AM
I do not know where the post I was responding to went .. but whoever it was told me that when I created the button object [UIButton buttonWithType:], it was autoreleased. When I released it, it crashed. That was SDK version 1, this is 5, so things are different. However, the idea is the same: never release variables twice.

My new book by the Big Nerd Ranch guy stated that if you try to release an autorelease object you will get an error and cannot compile.

Is this still an issue?

Duke Leto
May 27, 2008, 01:47 PM
Unfortunately, it does compile. Meaning that if you have that mistake, you will not know it until later and it will not be as descriptive as an error message on a particular line.

spstanley
May 27, 2008, 04:12 PM
Boy do I feel dumb. I was using a local reference to my view, then releasing it! Don't try this at home:

- (void)viewDidLoad
{
UIView *view = self.view;
.
.
.
[view release];
}

sujithkrishnan
Jul 2, 2008, 05:19 AM
What about this code:

#import "MasterViewController.h"
#import "UntitledAppDelegate.h"
#import "UserNameViewController.h"

@implementation MasterViewController

@synthesize appController;
@synthesize tableView;

- (id)init
{
if (self = [super init]) {
self.title = @"Categories";
}
return self;
}

- (void) inspectAction:(id) sender
{
}

- (void)loadView {
UIButton *inspectButton = [UIButton buttonWithType:UIButtonTypeNavigation];
[inspectButton setTitle:@"A Button" forStates:UIControlStateNormal];
[inspectButton addTarget:self action:@selector(inspectAction:) forControlEvents:UIControlEventTouchUpInside];
self.navigationItem.customRightView = inspectButton;
[inspectButton release];

tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStylePlain];
tableView.delegate = self;
tableView.dataSource = self;
tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
self.view = tableView;
}


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}

- (void)dealloc
{

tableView.dataSource = nil;
tableView.delegate = nil;
[tableView release];
[userNameViewController release];
[super dealloc];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [appController.masterList count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath withAvailableCell:(UITableViewCell *)availableCell
{
UISimpleTableViewCell *cell = nil;
if (availableCell != nil) {
// Use the existing cell if it's there
cell = (UISimpleTableViewCell *)availableCell;
} else {
cell = [[[UISimpleTableViewCell alloc] initWithFrame:CGRectZero] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}

// Get the object to display and set the value in the cell
NSDictionary *itemAtIndex = (NSDictionary *)[appController.masterList objectAtIndex:indexPath.row];
cell.text = [itemAtIndex objectForKey:@"title"];
return cell;
}


- (void)tableView:(UITableView *)tableView selectionDidChangeToIndexPath:(NSIndexPath *)newIndexPath fromIndexPath:(NSIndexPath *)oldIndexPath {

// Create the detail view lazily
if (userNameViewController == nil) {
userNameViewController = [[UserNameViewController alloc] init];
}
// Set the detail controller's inspected item to the currently-selected item
userNameViewController.detailItem = [appController.masterList objectAtIndex:newIndexPath.row];
[[self navigationController] pushViewController:userNameViewController animated:YES];
}
@end

Yes there is a button called "A Button" that does nothing. I was just testing out navigation Items.

Duke....

How making nil and releasing differs???

is it ok to do release like

[myObject release];
myObject = nil;

OR the following is enough???

myObject = nil;



My app crashing sometimes on statup....

Also i am getting mem-leaks for following line...


cell.image = [UIImage imageWithData:[NSData dataFromURL:[NSURL urlWithString:myImagePath]]];


Help plz...

Enuratique
Jul 2, 2008, 10:21 AM
Duke....

How making nil and releasing differs???

is it ok to do release like

[myObject release];
myObject = nil;

OR the following is enough???

myObject = nil;



My app crashing sometimes on statup....

Also i am getting mem-leaks for following line...


cell.image = [UIImage imageWithData:[NSData dataFromURL:[NSURL urlWithString:myImagePath]]];


Help plz...


[myObject release];
myObject = nil;


Is perfectly fine, but you probably don't need to set the reference pointed to by myObject to nil unless that's how you tell elsewhere in your code whether the reference points to allocated memory or not. In general, it's not needed and unless you really need to know whether that pointer points to a valid reference or not, just be diligent about your releases as you can get in to trouble if myObject was allocated by an Apple API object and you've just set it to nil and then the API object tries to use it (for example, a UIView).

Doing

myObject = nil;


Is BAD! Do NOT do this. You are essentially orphaning your reference at that point, and it cannot be released later on.

dleute
Jul 13, 2008, 12:20 AM
I highly recommend starting with some apple demo code and molding that into what you need your app to do. Do it one step at a time so you can see where your app crashes. It helped me especially through the early beta. It also helps you understand excellent design practices.

--Derrek

------
iScale: iPhone nutrition tracking made easy!
http://www.allofzero.com/