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

ArtOfWarfare

macrumors G3
Original poster
Nov 26, 2007
9,561
6,059
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:
Added an object to clippings.
Number of clippings: 0

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.
 

ArtOfWarfare

macrumors G3
Original poster
Nov 26, 2007
9,561
6,059
You have initialized the mutable array, right?

... 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?
 
Last edited:

North Bronson

macrumors 6502
Oct 31, 2007
395
1
San José
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];
}
 

LostSoul80

macrumors 68020
Jan 25, 2009
2,136
7
I'd go with this:

Code:
clippings = [[NSMutableArray alloc] init];
[clippings addObjectsFromArray:[[NSUserDefaults standardUserDefaults] arrayForKey: @"clippings"]];
 

ArtOfWarfare

macrumors G3
Original poster
Nov 26, 2007
9,561
6,059
I'd go with this:

Code:
clippings = [[NSMutableArray alloc] init];
[clippings addObjectsFromArray:[[NSUserDefaults standardUserDefaults] arrayForKey: @"clippings"]];

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. :)
 
Last edited:

North Bronson

macrumors 6502
Oct 31, 2007
395
1
San José
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.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.