0

I have this method that is not working the way I need. It create a MKPolyline "animated": let's say I have 85 points. Each polyline that connects these points is created 0.1 second after the previous. For this, it call itself through performSelector:withObject:afterDelay:.

-(void)addOverlaysFromPointsWithStartFromAndPoints:(NSArray *)arguments
{

    NSLog(@"end: %@ / coordinates count: %d",[arguments objectAtIndex:0],[[arguments objectAtIndex:1] count]);

    CLLocationCoordinate2D *locations = malloc(sizeof(CLLocationCoordinate2D)*2);
    Location *loc1 = (Location *)[[arguments objectAtIndex:1] objectAtIndex:[(NSNumber *)[arguments objectAtIndex:0] intValue]-1];
    Location *loc2= (Location *)[[arguments objectAtIndex:1] objectAtIndex:[(NSNumber *)[arguments objectAtIndex:0] intValue]];
    locations[0] = loc1.location;
    locations[1] = loc2.location;
    routeLine = [MKPolyline polylineWithCoordinates:locations count:2];

    [self.map addOverlay:routeLine];

    if(([(NSNumber *)[arguments objectAtIndex:0] intValue]+1) < [[arguments objectAtIndex:1] count])//add more overlays after delays unless this is the endpoint
    {
        NSArray *parameters = [NSArray arrayWithObjects:[NSNumber numberWithInt:[(NSNumber *)[arguments objectAtIndex:0] intValue] + 1],[arguments objectAtIndex:1],nil];
        [self performSelector:@selector(addOverlaysFromPointsWithStartFromAndPoints:) withObject:parameters afterDelay:0.1];
    }

}

In my case, I have kind of 3 subroutes to be created, so initially I have arrays with 7, 68 and 85 indexes each one. Check this log:

2013-02-21 10:31:22.372 SIGView[329:907] end: 1 / coordinates count: 7
2013-02-21 10:31:22.433 SIGView[329:907] end: 1 / coordinates count: 68
2013-02-21 10:31:22.528 SIGView[329:907] end: 1 / coordinates count: 85
2013-02-21 10:31:22.541 SIGView[329:907] end: 2 / coordinates count: 85
2013-02-21 10:31:22.542 SIGView[329:907] end: 2 / coordinates count: 85
2013-02-21 10:31:22.650 SIGView[329:907] end: 2 / coordinates count: 85
2013-02-21 10:31:22.653 SIGView[329:907] end: 3 / coordinates count: 85
2013-02-21 10:31:22.655 SIGView[329:907] end: 3 / coordinates count: 85
2013-02-21 10:31:22.796 SIGView[329:907] end: 3 / coordinates count: 85
2013-02-21 10:31:22.798 SIGView[329:907] end: 4 / coordinates count: 85
2013-02-21 10:31:22.801 SIGView[329:907] end: 4 / coordinates count: 85
2013-02-21 10:31:22.898 SIGView[329:907] end: 4 / coordinates count: 85
2013-02-21 10:31:22.905 SIGView[329:907] end: 5 / coordinates count: 85
2013-02-21 10:31:22.909 SIGView[329:907] end: 5 / coordinates count: 85
2013-02-21 10:31:23.013 SIGView[329:907] end: 5 / coordinates count: 85
(...)

I seems like when the method is first called for each array, it works fine but then it assumes the last array (that contains 85 objects). So, i have only one "route" created and animated.

The log should look something like:

2013-02-21 10:31:22.372 SIGView[329:907] end: 1 / coordinates count: 7
2013-02-21 10:31:22.433 SIGView[329:907] end: 1 / coordinates count: 68
2013-02-21 10:31:22.528 SIGView[329:907] end: 1 / coordinates count: 85
2013-02-21 10:31:22.541 SIGView[329:907] end: 2 / coordinates count: 7
2013-02-21 10:31:22.542 SIGView[329:907] end: 2 / coordinates count: 68
2013-02-21 10:31:22.650 SIGView[329:907] end: 2 / coordinates count: 85
2013-02-21 10:31:22.653 SIGView[329:907] end: 3 / coordinates count: 7
2013-02-21 10:31:22.655 SIGView[329:907] end: 3 / coordinates count: 68
2013-02-21 10:31:22.796 SIGView[329:907] end: 3 / coordinates count: 85

I hope you understand the problem and help how to get this fixed.

Thanks in advance!

EDIT

Here is how the method is called:

NSArray *argumentsToOverlay = [NSArray arrayWithObjects:[NSNumber numberWithInt:1],locationsToLoadRegion, nil];

[self addOverlaysFromPointsWithStartFromAndPoints:argumentsToOverlay];

This part of the code is called three times when the locationsToLoadRegion array contains respectively 7, 68 and 85 objects.

The problem start when performSelector: is called the first time.

EDIT

- (void)createPathWithCoordinates:(NSMutableArray *)coordinates{

    int count;

// This for run through all sub routes
    for (NSArray *trackings in coordinates) {
        [locationsToLoadRegion removeAllObjects];

        count = [trackings count];

        if (count > 1){

            // This for save the coordinates available for sub route
            for (NSInteger index = 0; index < count; index++)
            {
                Location *tempLocation = [trackings objectAtIndex:index];
                [locationsToLoadRegion addObject:tempLocation];
            }

            NSArray *argumentsToOverlay = [NSArray arrayWithObjects:[NSNumber numberWithInt:1],locationsToLoadRegion, nil];

            [self addOverlaysFromPointsWithStartFromAndPoints:argumentsToOverlay];

        }

    }
}
CainaSouza
  • 1,417
  • 2
  • 16
  • 31
  • I don't really follow the question, I must say. But I did spot a `malloc()` and no `free()`, but given you always `malloc()` 2 objects, why use it at all? – trojanfoe Feb 21 '13 at 14:01
  • Also, following your code [arguments objectAtIndex:1] does never change, which means there must be something else influencing the behavior. (Or am I missing something?) – Daniel Feb 21 '13 at 14:07
  • I edited the question including how the log should look like. I believe you can understand better with info above. And I've really forgotten to call free(). I did it now! Thanks! – CainaSouza Feb 21 '13 at 14:17
  • @simpleBob the object at index 1 is always the array with the coordinates – CainaSouza Feb 21 '13 at 14:18
  • @CainaSouza yes, but you never seem to change it. So how do you even get from count: 7 to count:68 and to count:85? – Daniel Feb 21 '13 at 14:24
  • Hm. Then it might be a problem of how you construct the first three parameter arrays, especially the second half. Please post the code how you call this. – w-m Feb 21 '13 at 14:24
  • It seems to me that you do not reset [arguments objectAtIndex:1] when [arguments objectAtIndex:0] changes – Daniel Feb 21 '13 at 14:27
  • I edited the question including the code where the method is called. – CainaSouza Feb 21 '13 at 14:28
  • Do you reuse locationsToLoadRegion? How are they created? – w-m Feb 21 '13 at 14:31
  • Yes! I edited the question again – CainaSouza Feb 21 '13 at 14:36
  • Thank you guys for your attention and help! – CainaSouza Feb 21 '13 at 15:06

2 Answers2

0
    NSArray *parameters = [NSArray arrayWithObjects:...];
    [self performSelector:... withObject:parameters ...];

You create an autoreleased array (parameters) which will be destroyed before the next call of the function. It's a mere coincidence that you still get usable data instead of an exception/crash.

A solution would be to retain the parameters as properties of the calling class, for example.

w-m
  • 10,772
  • 1
  • 42
  • 49
0

Try this:

NSArray *argumentsToOverlay = [NSArray arrayWithObjects:
    [NSNumber numberWithInt:1],
    [[locationsToLoadRegion copy] autorelease],
    nil];
w-m
  • 10,772
  • 1
  • 42
  • 49