Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

medasmx

macrumors member
Original poster
Nov 9, 2008
89
0
I am currently working through the Big Nerd Ranch iPhone book, and am fooling around with different tableView projects. In one of these, I created a separate class to contain a series of strings. These will be used in a navigation controller, to be inputted in text fields in a detail view. In my class I made it simple, having my class start with only one string. I was getting an error when I ran the project, so I figured this class I created had a problem. So I tried to use it in a simple objective-c project. The code is listed below. The output of this should be "jimmy". Instead I get the following --

"2010-10-14 12:00:27.561 ClassTest[8552:a0f] <Name: 0x10010c760>"

Code:
#import <Foundation/Foundation.h>

@interface Name : NSObject 
{
    NSString *_first;
}

@property (nonatomic, retain) NSString *first;

+ (id)nameWithFirst:(NSString *)first;

- (id)initWithFirst:(NSString *)first;

@end

#import "Name.h"

@implementation Name

@synthesize first = _first;

- (void)dealloc
{
    [_first release];
    
    [super dealloc];
}

+ (id)nameWithFirst:(NSString *)first
{
	Name *name = [[self alloc] initWithFirst:first];
				  
	return [name autorelease];
}
				  
- (id)init
{
	return [self initWithFirst:@""];
}				  
				  
				  
- (id)initWithFirst:(NSString *)first
{
	self = [super init];
		
	[self setFirst:first];
		
	return self;
}

+(id)someName
{
	Name*newName=[[self alloc]initWithFirst:@"jimmy"];
	return newName;
}

@end

#import <Foundation/Foundation.h>
#import "Name.h"

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSLog(@"%@",[Name someName]);
    [pool drain];
    return 0;
}

Any help is appreciated. Thanks.

Adam
 
The output of this should be "jimmy".
This expectation is wrong. The implementation of Name doesn't override -description. Therefore, the NSString produced for a "%@" conversion specifier will be the -description method provided by NSObject.

EDIT:
By the way, +someName is leaking its returned Name.
You should refactor +someName so it calls +nameWithFirst:.
 
Try
Code:
NSLog(@"%@", [[Name someName] first]);
It looks like you forgot to actually ask your new object for the string you wanted.
 
follow-up question

Thanks, catfishMan. That worked. This is a follow-up. Below uses the Name class that I used in the prior example. I think "setText:[name first]" is not the appropriate format. The code below appears in the detail view.

Code:
- (void)viewWillAppear:(BOOL)animated
{
	[super viewWillAppear:animated];
	
	[myTextField setText:[name first]];
}

I used a similar format below. "name" is a instance of the Name class. Again, I believe the problem lies in the "setFirst:[name first]" statement.

Code:
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
	ItemDetailViewController *controller = [[ItemDetailViewController alloc]init];
	
	NSUInteger index = [indexPath row];
	id name = [self.myArray objectAtIndex:index];
	
	[controller setName:name];
	[controller setFirst:[name first]];
	
	[[self navigationController] pushViewController:controller
										   animated:YES];
	[controller release];
}

Thanks again for any help.
Adam
 
You've posted some code, but you haven't identified what the problem is.

If it has compiler errors or warnings, then post the exact text of the error or warning.
 
My apologies. Below is the error I get. This comes up when I select one of the rows of the tableView.

"*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFString first]: unrecognized selector sent to instance 0x4054'"

"first" is an NSString property of the Name class.
 
Code:
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
	ItemDetailViewController *controller = [[ItemDetailViewController alloc]init];
	
	NSUInteger index = [indexPath row];
[COLOR="Red"]	id [/COLOR]name = [self.myArray objectAtIndex:index];
	
	[controller setName:name];
	[controller setFirst:[name first]];
	
	[[self navigationController] pushViewController:controller
										   animated:YES];
	[controller release];
}

The red-hilited fragment of code is removing any type-checking that the compiler can do. In particular, the use of id type instead of a more specific type, such as NSString* or Name*. Exactly what type are you expecting from the array at that point? Whatever it is, why aren't you declaring the variable as that type?

You haven't posted enough code to completely identify the problem. In particular, you haven't shown what types of objects are added to myArray. My guess is NSString references, based on the exception error message, which identifies NSCFString as the class of the object being sent a -first message. If you're adding NSStrings, then it's completely wrong to expect them to be Name objects; NSString doesn't respond to the -first message.

And you haven't posted any code from ItemDetailViewController, so it's impossible to tell if it's doing the right thing in its setName: or setFirst: methods.

Overall, this looks like you're in over your head, and you should go back and review the purpose and use of specific object types; i.e. the use of NSString* or other types, instead of the generic id type. There may be other things you should also review, but without seeing more code it's impossible to suggest anything.
 
My apologies. Below is the error I get. This comes up when I select one of the rows of the tableView.

"*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFString first]: unrecognized selector sent to instance 0x4054'"

"first" is an NSString property of the Name class.

Well apparently you are asking an NSString for its first property which is not there.
I would suspect that the id name returned from your array is in fact a string.
(which is probably why you put the id there in the first place ) ;)
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.