سؤال

So, I'm trying to build an array of CGPoints by breaking an NSString, typically look like this:

31.241854,34.788867;31.241716,34.788744;31.242547,34.787585;31.242661,34.787719

Using this code:

- (NSMutableArray *)buildPolygon:(NSString *)polygon
{
    NSMutableArray *stringArray = [[NSMutableArray alloc] init];
    [stringArray addObject:[polygon componentsSeparatedByString:@";"]];
    NSMutableArray *polygonArray = [[NSMutableArray alloc] init];

    for (int i=0; i < polygonArray.count; i++)
    {
        NSArray *polygonStringArray = [[NSArray alloc] init];
        polygonStringArray = [[stringArray objectAtIndex:i] componentsSeparatedByString:@","];
        CGFloat xCord = [[polygonStringArray objectAtIndex:0] floatValue];
        CGFloat yCord = [[polygonStringArray objectAtIndex:1] floatValue];
        CGPoint point = CGPointMake(xCord, yCord);
        [polygonArray addObject:[NSValue valueWithCGPoint:point]];
    }

    NSLog(@"return polygonArray: %@", polygonArray);
    return polygonArray;
}

But eventually I get an empty array. What I'm doing wrong?

هل كانت مفيدة؟

المحلول

You're defining polygonArray as an empty array just before the start of your for loop. You should define polygonArray like:

NSArray *polygonArray = [polygon componentsSeparatedByString:@";"];

And you don't even need to bother with that stringArray variable.

نصائح أخرى

You have confusion over alloc & init, and one simple typo...

The confusions first:

NSMutableArray *stringArray = [[NSMutableArray alloc] init];

This creates a new NSMutableArray and stores a reference to it in stringArray. All good so far.

[stringArray addObject:[polygon componentsSeparatedByString:@";"]];

And this obtains a reference to an NSArray ([polygon componentsSeparatedByString:@";"]) and adds it as a single element to the mutable array referenced by stringArray. There is nothing wrong per se with this, but it is not what you want in this case - you just want the array returned by componentsSeparatedByString:. You do this with:

NSArray *stringArray = [polygon componentsSeparatedByString:@";"];

Which takes the reference returned by componentsSeparatedByString: and stores it in the variable stringArray - no alloc or init required as you are not creating the array yourself. You don't even own this array, so if you are using MRC there is no need to release it later.

NSArray *polygonStringArray = [[NSArray alloc] init];

Now this allocates an immutable empty array and stores a reference to it in polygonStringArray. This is not a very useful array, as it contains nothing and cannot be modified! But you don't keep it around long...

polygonStringArray = [[stringArray objectAtIndex:i] componentsSeparatedByString:@","];

This obtains a reference to an array from componentsSeparatedByString: and stores it in polygonStringArray. If you are using MRC this will cause a leak - your pointless zero-length array created above will leak, and a new zero-length array will be created and leaked every time around the loop.

You are confused over allocation - you only need to allocate things you are creating; when you receive a reference to an already allocated object you only need to store that reference. (If using MRC you may also need to retain/release/autorelease it as well - but let's stick with ARC.) So all you needed here was:

NSArray *polygonStringArray = [[stringArray objectAtIndex:i] componentsSeparatedByString:@","];

Now your code is almost correct, just one typo:

for (int i=0; i < polygonArray.count; i++)

Well you are filling polygonArray in this loop and it starts off as empty, what you need is stringArray.count.

HTH

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top