count returns 0 after adding an object to NSMutableArray?

Discussion in 'iOS Programming' started by ArtOfWarfare, Sep 3, 2011.

  1. ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #1
    clippings is an ivar declared as a pointer to an NSMutableArray.

    Here's the code in -(void)viewWillAppear:(BOOL)animated
    Code:
    clippings = [[[[NSUserDefaults standardUserDefaults] arrayForKey:@"clippings"] mutableCopy] retain];
    if ([clippings count] == 0) [clippings addObject:[UIPasteboard generalPasteboard].string];
    else [clippings insertObject:[UIPasteboard generalPasteboard].string atIndex:0];
    NSLog(@"Added an object to clippings.");
    NSLog(@"Number of clippings: %i", [clippings count]);
    And the output that is logged is:
    What am I doing wrong here? I know that [UIPasteboard generalPasteboard].string is not nil, because it's displaying what's on that paste board in a UILabel elsewhere in my program.
     
  2. LostSoul80 macrumors 68020

    LostSoul80

    Joined:
    Jan 25, 2009
    #2
    You have initialized the mutable array, right?
     
  3. ArtOfWarfare, Sep 3, 2011
    Last edited: Sep 3, 2011

    ArtOfWarfare thread starter macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #3
    ... no...

    I changed the line where I fetch it from the NSUserDefaults to this:
    Code:
    clippings = [[NSMutableArray arrayWithArray:[[[NSUserDefaults standardUserDefaults] arrayForKey:@"clippings"] mutableCopy]] retain];
    It works now... but it looks incredibly messy. Is there some single method that will do all this for me?
     
  4. North Bronson macrumors 6502

    Joined:
    Oct 31, 2007
    Location:
    San José
    #4
    It shouldn't be necessary to retain the mutable copy. The copy gives you ownership. The retain feels redundant and would require an extra release later.

    I would just:

    Code:
    clippings = [[[NSUserDefaults standardUserDefaults] arrayForKey: @"clippings"] mutableCopy];
    
    if (clippings == nil)
    {
        clippings = [[NSMutableArray alloc] init];
    }
     
  5. LostSoul80 macrumors 68020

    LostSoul80

    Joined:
    Jan 25, 2009
    #5
    I'd go with this:

    Code:
    clippings = [[NSMutableArray alloc] init];
    [clippings addObjectsFromArray:[[NSUserDefaults standardUserDefaults] arrayForKey: @"clippings"]];
     
  6. ArtOfWarfare, Sep 3, 2011
    Last edited: Sep 3, 2011

    ArtOfWarfare thread starter macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #6
    I like this a lot!

    I changed it to this though:
    Code:
    clippings = [[NSMutableArray alloc] initWithArray:[[NSUserDefaults standardUserDefaults] arrayForKey:@"clippings"]];
    Just one line that is about as short and easy to read as the second line of your example. And the code runs flawlessly on device. :)
     
  7. North Bronson macrumors 6502

    Joined:
    Oct 31, 2007
    Location:
    San José
    #7
    One slight issue might be that certain objects in the Foundation framework will crash or fail if you try to initialize them with nil-values. For example, if you do something like:

    Code:
    NSString *file = nil;
    
    NSArray *newArray = [[NSArray alloc] initWithContentsOfFile: file];
    
    if (newArray)
    {
        NSLog(@"good");
        
        [newArray release];
    }
    your code will run, but the array will be a nil-value.

    On the other hand, if you try something like:

    Code:
    NSString *string = nil;
    
    NSURL *newURL = [[NSURL alloc] initWithString: string];
    
    if (newURL)
    {
        NSLog(@"good");
        
        [newURL release];
    }
    your application will crash.

    For those reasons, I would suggest it is good-form to fall into the habit of checking to see that objects are non-nil before passing them to Foundation's initWith. . . family of methods.
     

Share This Page