Some doubts with classes instances...

Discussion in 'iOS Programming' started by skunkio, Apr 26, 2010.

  1. skunkio macrumors newbie

    Joined:
    Apr 25, 2010
    #1
    Hi all,
    i'm going to be a bit confused trying to initialize a class within another class.
    My test app has inside:

    • Test
    • TestViewController
    • RootViewController

    classes (each one has .h and .m file).
    RootViewController has inside a Table; my scope is add one item into the table, then click it and see in a different view some details. So i created the following code:

    Test.h
    Code:
    #import <Foundation/Foundation.h>
    
    @interface Test : NSObject {
    	NSString *name;
    	NSString *description;
    }
    
    @property (nonatomic, retain) NSString * name;
    @property (nonatomic, retain) NSString * description;
    
    - (id) initWithName: (NSString *) newName
    	    description: (NSString *) newDescription;
    @end
    TestViewController.h
    Code:
    #import <UIKit/UIKit.h>
    
    @class Test;
    
    @interface TestViewController : UIViewController <UITextFieldDelegate> {
    	UITextField *name;
    	UITextField *description;
    	
    	Test *test;
    }
    
    @property (nonatomic, retain) IBOutlet UITextField *name;
    @property (nonatomic, retain) IBOutlet UITextField *description;
    @property (nonatomic, retain) Test *test;
    
    @end
    RootViewController.h
    Code:
    @class Test;
    @class TestViewController;
    
    @interface RootViewController : UITableViewController {
    	NSMutableArray *listTests;
    	
    	TestViewController *testController;
    }
    
    @property (nonatomic, retain) TestViewController *testController;
    
    @end
    RootViewController.m
    Code:
    #import "RootViewController.h"
    #import "Test.h";
    #import "TestViewController.h";
    
    @implementation RootViewController
    
    @synthesize eventController;
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
    	listTests = [[NSMutableArray alloc] init];
    	
    	Test *test = [[Test alloc] initWithName:@"Primo test" description:@"Questo è il primo test inserito"];
    	[listTests addObject:test];
    	[test release];
    	
    	TestViewController *newTestController = [[TestViewController alloc] init];
    	self.testController = newTestController;
    	
        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        self.navigationItem.leftBarButtonItem = self.editButtonItem;
    }
    
    [cut...]
    
    // Override to support row selection in the table view.
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
     	Test *selectedTest = [listTests objectAtIndex:indexPath.row];
    	self.TestController.test = selectedTest;
    	[self.navigationController pushViewController:TestController animated:YES];
    }
    
    This is what happen now:
    - i'm able to add one item into the grid
    - i'm able to push the item and open the second view

    This is what i want:
    - add one item into the grid (ok)
    - initialize TestViewController and initialize automatically also Test in the same class (TestViewController) (KO)
    - touch the item (ok)
    - visualize TestViewController view popolate as the item added by code inside the grid, the same i touched before. (KO)

    I try to draw the structure

    [RootViewController] -->initializes--> [TestViewController] --here i want that TestViewController initializes [Test]

    Now when i try to initialize Test inside TestViewController the app dies.

    How can i initialize a class and initialize a second one within the firts? I hope my request is clear :)

    Ciao,
    stè
     
  2. skunkio thread starter macrumors newbie

    Joined:
    Apr 25, 2010
    #2
    Adding the red row below:

    Code:
    Test *selectedTest =[listTests objectAtIndex:indexPath.row];
    self.TestController.test = selectedTest;
    [COLOR="Red"]
    NSLog(@"count %i", [listTests count]);
    	
    if (selectedTest != nil) {
    	NSLog(@"diverso da null");
    	NSLog(@"name_2: %@", selectedTest.name);
    } else {
    	NSLog(@"null");
    }
    [/COLOR]
    [self.navigationController pushViewController:TestController animated:YES];
    
    i get this error:

    Code:
    2010-04-26 19:59:13.936 TableView[732:20b] count 1
    2010-04-26 19:59:13.937 TableView[732:20b] diverso da null
    2010-04-26 19:59:13.940 TableView[732:20b] *** -[UICGColor name]: unrecognized selector sent to instance 0x3e1b7c0
    2010-04-26 19:59:13.942 TableView[732:20b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[UICGColor name]: unrecognized selector sent to instance 0x3e1b7c0'
    2010-04-26 19:59:13.943 TableView[732:20b] Stack: (
        8307803,
        2437586491,
        8689723,
        8259190,
        8111810,
        12411,
        23906886,
        23890052,
        2838954,
        8092352,
        8088648,
        87573,
        87770,
        23633839,
        10920,
        10774
    )
    
    There is 1 item inside my array, selectTest is not null but i have an error when i try to read selectedTest.name

    Ciao,
    stè
     
  3. skunkworker macrumors regular

    Joined:
    Sep 9, 2007
    #3
    Is Test an autoreleased object?
    Cause if you add it to the array there is no need to then go and release it.
    On this line, try changing this in the code.

    Code:
    	Test *test = [[Test alloc] initWithName:@"Primo test" description:@"Questo è il primo test inserito"];
    	[listTests addObject:test];
    	[test release];
    to

    Code:
    	Test *test = [[Test alloc] initWithName:@"Primo test" description:@"Questo è il primo test inserito"];
    	[listTests addObject:test];
    
    or you could even do it like this.
    Code:
    [listTests addObject:[[Test alloc] initWithName:@"Primo test" description:"Questo è il primo test inserito"]];
    
    but make sure to add in an autorelease in the creation of the object.
     
  4. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #4
    If test is not an autoreleased object, then this code is perfectly fine:
    Code:
    	Test *test = [[Test alloc] initWithName:@"Primo test" description:@"Questo è il primo test inserito"];
    	[listTests addObject:test];
    	[test release];
    skunkworker, I think you are distracting from the error at hand with all this autorelease talk.

    skunkio, somehow your code thinks that selectedTest is of type UICGColor. How is that possible?
     
  5. skunkio thread starter macrumors newbie

    Joined:
    Apr 25, 2010
    #5


    Hi dejo, i don't know how and why this is possible. I removed the line

    [test release]

    as per skunkworker suggestion the code now works :confused:
    I don't understood the relation between my array and the individual test object.
    Looks like the array has a reference to the real object used to fill the array...otherwise, why, releasing test my array is not able to reference the item inside itself with the index 1?!?!?
    I hope skunkworker will be able to explain better...

    thanks,
    stè
     
  6. skunkworker macrumors regular

    Joined:
    Sep 9, 2007
    #6
    Well when you add an object to a NSMutableArray, it bumps its retain count by 1. But when you go to retrieve the object it is added into an autorelease pool and returned to you. I think this is correct.

    Just searching for UICGColor on google returned this similar problems.
    http://www.iphonedevsdk.com/forum/i...ngth-unrecognized-selector-sent-instance.html
    http://stackoverflow.com/questions/...type-uicgcolor-during-cellforrowatindexpath-e
     
  7. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #7
    You sure about that?
     
  8. VMMan macrumors 6502a

    Joined:
    Mar 29, 2009
    #8
    I just glanced quickly at your code and noticed that you spelled testController with a capitalized "T" twice as TestController.
     

Share This Page