objectiveC-class question

Discussion in 'iOS Programming' started by medasmx, Oct 14, 2010.

  1. medasmx macrumors member

    Joined:
    Nov 9, 2008
    #1
    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
     
  2. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #2
    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:.
     
  3. Catfish_Man macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #3
    Try
    Code:
    NSLog(@"%@", [[Name someName] first]);
    It looks like you forgot to actually ask your new object for the string you wanted.
     
  4. medasmx thread starter macrumors member

    Joined:
    Nov 9, 2008
    #4
    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
     
  5. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #5
    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.
     
  6. medasmx thread starter macrumors member

    Joined:
    Nov 9, 2008
    #6
    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.
     
  7. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #7
    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.
     
  8. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #8
    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 ) ;)
     

Share This Page