views:

321

answers:

3

Hi, I need to pick string valur from an NSMutableArray then save it into a plist. I've builded an NSMutableArray to display infos in table View. Maximum allowed index is 8. (paste just two in example)

The problem if the String doesn't exist, I get the following error: sDict is a dictionary for saving datas to a property list file.

the code:

- (IBAction)save:(id)sender {
(...)
NSString *One;
NSString *Two;
...etc

if ([self.smOne objectAtIndex:0])
One = [self.smOne objectAtIndex:0];
if ([self.smOne objectAtIndex:1])
Two = [self.smOne objectAtIndex:1];
...etc

if (One)
[sDict setObject:[self.smTwo objectAtIndex:0] 
                forKey:[UserM stringByAppendingString:One]];
[sDict setObject:[self.smThree objectAtIndex:0] 
                forKey:[UserS stringByAppendingString:One]];
[sDict setObject:[self.smFour objectAtIndex:0] 
                forKey:[UserP stringByAppendingString:One]];


if (Two)
[sDict setObject:[self.smTwo objectAtIndex:1] 
                 forKey:[UserM stringByAppendingString:Two]];
[sDict setObject:[self.smThree objectAtIndex:1] 
                 forKey:[UserS stringByAppendingString:Two]];
[sDict setObject:[self.smFour objectAtIndex:1] 
                 forKey:[UserParM stringByAppendingString:Two]];


 ...etc
 }

This code works if all objects are present, but fails if it miss one of the object at index. I really don't know how to check properly if the object is present or not, cause code above seem's to don't works well.

I've tried with [self.smOne count] but as problem to pass as a Int or String to make conditions with. Thanks for answer.

+2  A: 

it looks like you're explicitly checking smOne from indices 1 through 8. But you also mentioned that the array can have up to 8. So if it's missing, say, 6, 7 and 8, you'd still be calling [smOne objectAtIndex:6], which would result in an NSRangeException being raised as 6 is out of bounds for the array.

try this instead:

int i = 0;

for ( NSString *aString in self.smOne )
{

 [sDict setObject:[self.smTwo objectAtIndex:i] 
           forKey:[UserM stringByAppendingSting:aString]];
 [sDict setObject:[self.smThree objectAtIndex:i] 
           forKey:[UserS stringByAppendingString:aString]];
 [sDict setObject:[self.smFour objectAtIndex:i] 
           forKey:[UserP stringByAppendingString:aString]];

 i++;

}

it'll go through each object in the smOne array and add the object into sDict regardless of how many items you have in smOne.

also, be careful with how you're generating your keys. there's the possibility that [UserM stringByAppendingSting:aString] won't always be unique.

pxl
Well, your code is perfect; i was testing with an NSenumerator, but this is simpliest. Many thanks for explanations too. regards, ronan.
ronan
this is basically a shortcut to using NSEnumerator, called fast enumeration.
pxl
Fast enumeration is unrelated to NSEnumerator.
Chuck
http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocFastEnumeration.htmlfast enumeration is syntax that allows you to enumerate through a collection. so yes, while fast enumeration may be unrelated to NSEnumerator, using fast enumeration in the OP's case is a shortcut to doign NSEnumerator *e=[dict objectEnumerator]; id obj; while ((obj = [e nextobject]) != nil) {do stuff;}
pxl
A: 

Sorry to ask again but i have dificulties to find how to rebuild arrays from the key/string couple saved with the loop.

i've tried this:

int i = 0;
for (NSString *SMServ in [temp objectForKey:
                         [UserMen stringByAppendingFormat:@"%d",i]]){
    NSString *SMMem[i];
    SMMem[i] = [temp objectForKey:[UserMen stringByAppendingFormat:@"%d",i]];
    NSArray *theArray = [ NSArray arrayWithObjects:SMMem count:i];
    i++;    
    }

But nothing happens. if i try with for (i = 0; i < 9; i ++) and (i + 1) instead of [i], i get same bounds errors in the first example.

thanks again for help.

ronan
read apple's documentation: http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocFastEnumeration.html
pxl
A: 

Well, finally it ,works. Thanks for link to the documentation, i read too fast last time. I'm sure this is not the cleanest way, but it works with this loop:

for (key in sDict) {
    if ([sDict valueForKey:[UserMen stringByAppendingFormat:@"%d",i]]) {
      tempMe = [sDict valueForKey:[UserMen stringByAppendingFormat:@"%d",i]];
     if (tempMe) {
     [manArray insertObject:tempMe atIndex:(0 + a)];
     [bankArray insertObject:[NSString stringWithFormat:@"%d",i] atIndex:(0 + a)];
     a++;
     }
    }
    if ([sDict valueForKey:[UserSerial stringByAppendingFormat:@"%d",i]]) {
     SMSer = [sDict valueForKey:[UserSerial stringByAppendingFormat:@"%d",i]];
     if (SMSer) {
     [serArray insertObject:SMSer atIndex:(0 + b)];
     b++;
            }
    }
    if ([sDict valueForKey:[UserPart stringByAppendingFormat:@"%d",i]]) {
     SMPart = [sDict valueForKey:[UserPart stringByAppendingFormat:@"%d",i]];
     if (SMPart) {
     [partArray insertObject:SMPart atIndex:(0 + c)];
     c++;
       }
    }
    i++;
}
ronan
be careful where you're doing things like [serArray insertObject:SMSer atIndex:(0 + b)]; ... you can potentially be skipping over indices and create even more problems
pxl