1

Best related discussions I’ve turned up: Making an array of Objects in Objective-C.. Scanned through links that came up when I prepped this post.

Self-study mode, creating mini-apps to reinforce and extend ideas I get working on book tutorials. …………….

Goal: To store some number of objects (example class ‘Trip’) in a mutable array, contained in another object (example class ‘TourCompany’).

(portions of the two different class interface files)

    @interface Trip : NSObject
    @property (strong, nonatomic) NSString *travelToLocation;

……

        @interface TourCompany : NSObject
        @property (strong, nonatomic) NSMutableArray *trips ;

…… CODE AND GOAL IN PIECES....

1) Demonstrate that I created 3 trip objects and can access the travelToLocation ivar ....

        Trip *trip0 = [[Trip alloc] init];
        Trip *trip1 = [[Trip alloc] init];
        Trip *trip2 = [[Trip alloc] init];

        [trip0 setTravelToLocation:@"Vienna"];
        [trip1 setTravelToLocation:@"Mt. St. Helens"];
        [trip2 setTravelToLocation:@"Tenochtitlan"];

        NSString *somePlace1 = trip1.travelToLocation;

        NSLog(@" %@ %@, \n \t Let's LOOK at one particular trip ivar %@.", twoBlanks, nuLn, somePlace1);

     //  CONSOLE RESULTS
      //     Let's LOOK at one particular trip ivar Mt. St. Helens.

.... 2) Demonstrate that I
i) can store these 3 trip objects in a locally declared NSMutable Array ii) can access the travelToLocation ivar ....

     // put trip objects into a LOCALLY DECLARED mutable array
        NSMutableArray *localTripsArray = [NSMutableArray array ];

      //[myArray addObject: someOtherPerson]; - compare to a STackOverflow discussion

        [localTripsArray addObject:trip0];
     [localTripsArray addObject:trip1];
        [localTripsArray addObject:trip2];


        for (Trip *t in localTripsArray) {

            NSLog(@"\n \t ^^^Trip location in LOCAL TRIPS Mutable ARRAY is %@", t.travelToLocation );

     }



    /*
        CONSOLE RESULTS
     objectInMutableArrayMiniAppChallenge[521:f803] 
        ^^^Trip location in LOCAL TRIPS Mutable ARRAY is Vienna
2012-07-05 13:47:17.172 objectInMutableArrayMiniAppChallenge[521:f803] 
        ^^^Trip location in LOCAL TRIPS Mutable ARRAY is Mt. St. Helens
        2012-07-05 13:47:17.172 objectInMutableArrayMiniAppChallenge[521:f803] 
         ^^^Trip location in LOCAL TRIPS Mutable ARRAY is Tenochtitlan

        */

.... 3) BUT I cannot figure out why I am not storing these 3 objects an NSMutable Array ('trips') in an instance of my TourCompany class ('friendlySkiesTourCo') ... // NOW instantiate an object in my TourCompany class

    TourCompany *friendlySkiesTourCo = [[TourCompany alloc] init];

 // put those same objects into the trips ivar in that object
 //[myArray addObject: someOtherPerson]; 
    //     - compare to a STackOverflow discussion
    //only difference I see is that instead of locally declared 'myArray'
    //   I'm using an ivar that's a member of an object
 // I know there's are values in those objects, because I displayed them above


 [friendlySkiesTourCo.trips addObject:trip0];
    [friendlySkiesTourCo.trips addObject:trip1];
    [friendlySkiesTourCo.trips addObject:trip2];


    for (Trip *t in friendlySkiesTourCo.trips) {

NSLog(@"\n \t +++ Trip location in 'trips' mutable array in the object 'friendlySkiesTourCo', a TourCompany class object, is %@", t.travelToLocation );

    }


    /* Console NON-Results

    I never get any output from this NSLog directive
     I'll bet there is something pretty basic I don't understand
     No doubt, it's in the Gol Durned Manual online , but I'm not seeing it
     */

.... 4. Let's just double check that the problem is possibly a setting type problem ....
// I don't think I'm really putting the objects into this particular mutable array in the friendlySkies object correctly // Let's just check

 int howManyTripsInMutableArray = [friendlySkiesTourCo.trips count];

 NSLog(@"\n \tThere are %d trips for the friendlySkiesTour Co ", howManyTripsInMutableArray);

        /*

     Sure enough...

     2012-07-05 13:53:53.235 objectInMutableArrayMiniAppChallenge[555:f803] 
    There are 0 trips for the friendlySkiesTour Co 

    */

Thanks for any clues. I hope that I did this writeup succinctly and that you don't think I just didn't RTGDM (that's 'gol durn' in case you wondered), because I sure tried to.

Laurel

Community
  • 1
  • 1
LaurelS
  • 492
  • 2
  • 8
  • 22
  • Sorry, I can't seem to make the two lines for the second class interface file show up as code, despite editing and putting in a bunch of spaces. Plus I can't put carriage returns in this comment. It's a second class "@interface TourCompany : NSObject @property (strong, nonatomic) NSMutableArray *trips ; " – LaurelS Jul 06 '12 at 16:58
  • No, that writeup is far from succinct. Maybe if you boiled it down into a short summary of the problem you're having, I might bother to read it. – Adam Rosenfield Jul 06 '12 at 17:02
  • possible duplicate of [Cannot add items to an NSMutableArray ivar](http://stackoverflow.com/questions/7125326/cannot-add-items-to-an-nsmutablearray-ivar) and http://stackoverflow.com/questions/3683761/nsmutablearray-addobject-not-affecting-count and http://stackoverflow.com/questions/1827058/nsmutablearray-addobject-not-working – jscs Jul 06 '12 at 18:28

2 Answers2

3

I'm willing to bet you didn't initialize friendlySkiesTourCo.trips. ie

friendlySkiesTourCo.trips = [[NSMutableArray alloc] init];

EDIT

As @Chuck pointed out below in the comments, this allocation should really be done in the initializer method for the class:

@implementation TourCompany

-(id) init
{
    self = [super init];

    self.trips = [[NSMutableArray alloc] init];

    return self;
}
Dan F
  • 17,654
  • 5
  • 72
  • 110
  • Actually, you should be doing this in the TourCompany initializer. Requiring callers to set up the class's instance variables for it is probably bad form. – Chuck Jul 06 '12 at 17:04
  • @chuck you are correct, I just wasn't sure where exactly that is for him, I didn't want to read through all of the code to find the right place to put it – Dan F Jul 06 '12 at 17:11
  • Thanks Dan. NO, I double checked and I have this line before hand TourCompany *friendlySkiesTourCo = [[TourCompany alloc] init]; – LaurelS Jul 06 '12 at 17:11
  • @LaurelShimer You are indeed allocating `friendlySkiesTourCo`, however, are you allocating the array within it? Have you written `TourCompany`'s `init` method? Just because you allocated the class, doesn't mean you have allocated the members – Dan F Jul 06 '12 at 17:12
  • @LaurelShimer I made an edit to my post to demonstrate a more proper way of handling this allocation and initialization – Dan F Jul 06 '12 at 17:17
  • @Dan Hooray! +++ Trip location in 'trips' mutable array in the object 'friendlySkiesTourCo', a TourCompany class object, is Vienna ..... +++ Trip location in 'trips' mutable array in the object 'friendlySkiesTourCo', a TourCompany class object, is Mt. St. Helens 2012-07-06 10:20:08.522 objectInMutableArrayMiniAppChallenge[617:f803] +++ Trip location in 'trips' mutable array in the object 'friendlySkiesTourCo', a TourCompany class object, is Tenochtitlan 2012-07-06 10:20:08.522 objectInMutableArrayMiniAppChallenge[617:f803] There are 3 trips for the friendlySkiesTour Co – LaurelS Jul 06 '12 at 17:21
  • @LaurelShimer Glad to be of assistance. Remember, more or less everything in objective-c is a pointer, and must be allocated or assigned to something at some point before it can be used. – Dan F Jul 06 '12 at 17:22
  • @Chuck Sorry Was that you who put the code in for the init method? Maybe I should have 'hooray'ed you. Anyway. That works and SHE is very appreciative! Sorry that HER code was so lengthy. Boy, it's hard figuring out how much code/description to put in, to make it clear what I'm doing. OK, on with the next chapter in the book now. Thanks again. Oh, and I have to figure out how to vote up. I will try that again. – LaurelS Jul 06 '12 at 17:23
  • (Voting up question - hope this is OK to put here). So the up arrow as already marked as 2 and it seemed to indicate if I clicked that it would undo. So I clicked the checkmark. I hope that is right. I don't want my profile to say I never 'vote up', as though I don't appreciate help. ...Someday I plan to be answering questions out here. – LaurelS Jul 06 '12 at 17:25
  • @Dan So, I know that I need to allocate and init, except that I can often use (OK, they are sometimes called 'factory' methods, but there is another word for them I cannot remember) that will do the allocate and init for me. Is there something different about NSMutableArray (used in the 'TourCompany' class) than for NSString (in the 'Trip' class)? Because the Trip class was fine using the init it inherited from NSObject. Sorry, I can't move this to chat. I won't add anymore comments. – LaurelS Jul 06 '12 at 17:40
  • @LaurelShimer the primary difference is that when you are using the `NSString` in `Trip` you are assigning it an already constructed string (@"Vienna", @"Mt. St. Helens", @"Tenotchitlan"). just the same as you could assign an already constructed array to your `NSMutableArray` – Dan F Jul 06 '12 at 17:42
  • @Dan. Thank you for explaining that. I'm trying to really work on the concepts as well as getting code to run. – LaurelS Jul 06 '12 at 17:48
0

Does this help?

trips =  [NSMutableArray arrayWithCapacity:3];
trip *trip1 = [[trip alloc] init];
trip *trip2 = [[trip alloc] init];
trip *trip3 = [[trip alloc] init];

trip1.traveltolocation = @"vienna";

[trips addObject:trip1];
[trips addObject:trip2];
[trips addObject:trip3];
SJP
  • 1,330
  • 12
  • 21
  • Hey SJP, so are you redeclaring trips like a local variable? This doesn't seem like it's using the 'trips' ivar that is a member of my "TourCompany" class.... I can make this work when I use a local mutable array variable, but not when I attempt to put the objects into a member variable in an object that is of another class. – LaurelS Jul 06 '12 at 17:14