PerformSelector:withObject: не работает должным образом

У меня есть этот метод, который не работает так, как мне нужно. Он создает «анимацию» MKPolyline: допустим, у меня есть 85 точек. Каждая полилиния, соединяющая эти точки, создается через 0,1 секунды после предыдущей. Для этого он вызывает себя через 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];
    }

}

В моем случае мне нужно создать 3 подмаршрута, поэтому изначально у меня есть массивы с 7, 68 и 85 индексами в каждом. Проверьте этот журнал:

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
(...)

Мне кажется, что когда метод сначала вызывается для каждого массива, он работает нормально, но затем он предполагает последний массив (который содержит 85 объектов). Итак, у меня есть только один созданный и анимированный «маршрут».

Журнал должен выглядеть примерно так:

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

Я надеюсь, что вы понимаете проблему и поможете, как это исправить.

Заранее спасибо!

ИЗМЕНИТЬ

Вот как называется метод:

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

[self addOverlaysFromPointsWithStartFromAndPoints:argumentsToOverlay];

Эта часть кода вызывается три раза, когда массив locationsToLoadRegion содержит соответственно 7, 68 и 85 объектов.

Проблема начинается, когда performSelector: вызывается в первый раз.

ИЗМЕНИТЬ

- (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];

        }

    }
}

person CainaSouza    schedule 21.02.2013    source источник
comment
Я не очень понимаю вопрос, должен сказать. Но я заметил malloc(), а не free(), но если у вас всегда malloc() 2 объекта, зачем вообще его использовать?   -  person trojanfoe    schedule 21.02.2013
comment
Кроме того, следование вашему коду [arguments objectAtIndex:1] никогда не меняется, а это значит, что на поведение должно влиять что-то еще. (Или я что-то пропустил?)   -  person Daniel    schedule 21.02.2013
comment
Я отредактировал вопрос, включая то, как должен выглядеть журнал. Я считаю, что вы можете лучше понять с информацией выше. И я действительно забыл вызвать free(). Я сделал это сейчас! Спасибо!   -  person CainaSouza    schedule 21.02.2013
comment
@simpleBob объект с индексом 1 всегда является массивом с координатами   -  person CainaSouza    schedule 21.02.2013
comment
@CainaSouza да, но ты никогда не меняешь это. Итак, как вы вообще получаете от count: 7 до count: 68 и count: 85?   -  person Daniel    schedule 21.02.2013
comment
Хм. Тогда это может быть проблема того, как вы создаете первые три массива параметров, особенно вторую половину. Пожалуйста, напишите код, как вы это называете.   -  person w-m    schedule 21.02.2013
comment
Мне кажется, что вы не сбрасываете [arguments objectAtIndex:1] при изменении [arguments objectAtIndex:0]   -  person Daniel    schedule 21.02.2013
comment
Я отредактировал вопрос, включая код, в котором вызывается метод.   -  person CainaSouza    schedule 21.02.2013
comment
Используете ли вы повторно locationToLoadRegion? Как они создаются?   -  person w-m    schedule 21.02.2013
comment
Да! Я снова отредактировал вопрос   -  person CainaSouza    schedule 21.02.2013
comment
Спасибо ребята за внимание и помощь!   -  person CainaSouza    schedule 21.02.2013


Ответы (2)


Попробуй это:

NSArray *argumentsToOverlay = [NSArray arrayWithObjects:
    [NSNumber numberWithInt:1],
    [[locationsToLoadRegion copy] autorelease],
    nil];
person w-m    schedule 21.02.2013
comment
Это было решением! Спасибо, получилось именно так, как я хотел! Спасибо! - person CainaSouza; 21.02.2013

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

Вы создаете автоматически освобождаемый массив (параметры), который будет уничтожен перед следующим вызовом функции. Это простое совпадение, что вы по-прежнему получаете полезные данные вместо исключения/сбоя.

Решением было бы, например, сохранить параметры как свойства вызывающего класса.

person w-m    schedule 21.02.2013
comment
параметр будет сохранен, см. этот ответ - person Daniel; 21.02.2013
comment
Это зависит от того, использует ли он ARC или нет. - person trojanfoe; 21.02.2013
comment
Я не использую ARC, и объект сохраняется в параметре. Я пытался выделить массив, но не меняется... - person CainaSouza; 21.02.2013
comment
Вы правы, аргумент сохраняется. Это сбивает с толку, текущие документы NSObject ничего не говорят об этом. - person w-m; 21.02.2013