NSMutableArray из спрайтов, проблем с памятью? - PullRequest
1 голос
/ 14 июня 2011

У меня есть массив из десяти спрайтов; они все сидят в одной области экрана. Для простоты объяснения, я скажу, посередине, сложены друг на друга. Что мне нужно сделать, это взять верхний спрайт и сбросить его с экрана, проведя его вперед (снизу вверх). Когда у меня есть один спрайт, у меня нет проблем с этим; это когда у меня есть несколько спрайтов, у меня есть проблемы. Я добавляю элементы к слою так:

for(int i=0; i<maxCount; i++){
    CCSprite *x = [listOfItems objectAtIndex:i];

    //NSLog(@"(%f, %f)", x.position.x, x.position.y);

    [self addChild:x];
}

Они созданы на шаге выше:

for (int i=0; i<maxCount; i++) {
    CCSprite *o = [CCSprite spriteWithFile:@"image.png"];
    o.position = ccp(windowSize.width/2,windowSize.width/2);

    [listOfItems addObject:o];

    [o release];
}

Полагаю, реальная проблема в том, что я не знаю, как справиться с «текущий» топ. Итак, если у меня индекс массива 0 в качестве верхней части, я могу просто использовать сенсорный жест и «стряхнуть» его с экрана. Первый работает нормально, но как только я касаюсь второго, он вылетает с EXC_BAD_ACCESS. Вот метод TouchesBegan:

-(void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInView:[touch view]];
    location = [[CCDirector sharedDirector] convertToGL:location];
    startingPoint = location;

    //Trying something here....
    //if(current)
    //    [current release];

    current = [listOfItems objectAtIndex:currentPosition];
    [self reorderChild:current z:2];

    actionStartTime = [NSDate timeIntervalSinceReferenceDate];
}

Когда строки «Попробовать что-то здесь ...» не закомментированы, именно здесь происходит сбой, а когда они закомментированы, это происходит при назначении current. Я знаю, что здесь что-то упущено, но я просто не могу этого понять.

Ответы [ 3 ]

1 голос
/ 14 июня 2011

Посмотрите, как вы установили current - он установлен на [listOfItems objectAtIndex:currentPosition], который является объектом, которым вы не владеете. Таким образом, к следующему раунду этот объект мог быть освобожден, и отправка ему любого сообщения после его освобождения (включая release) является неопределенным поведением, которое приведет к EXC_BAD_ACCESS , если вам повезет . (Это может привести к гораздо более тонкому и трудному обнаружению ошибок, если вам не повезло.)

1 голос
/ 14 июня 2011

Если все ваши объекты добавлены в массив, я считаю, что самое простое, что нужно сделать, это установить разные теги для каждого объекта.

for(int i = 0; i < NUMOFOBJECTS; i++)
{
    CCSprite *sprite = blah blah whatever;

    // I do something like 100+i so that each time I want to
    // create different types of objects I can subtract the "100"
    // or whatever it is to get a base index value for arrays.
    sprite.tag = 100+i;
}

Внутри CCTouchesBegan вы проверяете касание, чтобы убедиться, что оно на предметах, а затем вы перебираете там свои предметы и перемещаете только предмет с правильным тегом.

for(CCSprite *sprite in objects)
{
     if(sprite.tag - 100 == [objectOrderList objectAtIndex:0].tag)
     {
          // Do whatever
     }
}

Считайте это псевдокодом, поскольку я просто пишу на макушке. В этой ситуации вы будете отслеживать порядок объектов в NSMutableArray, удаляя / заменяя / добавляя объекты при каждом изменении порядка.

1 голос
/ 14 июня 2011

Можно удалить [o release]; CCSprites создаются как автоматически выпущенные объекты.

Также, чтобы найти причину сбоя, попробуйте открыть консоль отладки, которая находится в меню «Выполнить».Последнее, что отображается в консоли, часто будет отображать сообщение о том, почему произошла ошибка.

...