2013-05-01 2 views
1

J'ai besoin d'implémenter une fonction récursive pour diviser une image en plusieurs petites images pour un jeu de puzzle.EXC_BAD_ACCESS code = 2 en méthode récursive avec ARC

modifier: Voici comment l'apparence de la méthode d'initialisation de classe ShapeObject (actuellement seulement cercles de soutien) // méthode d'initialisation de ShapeObject

//shape currently has only a property named radius (it's a circle) 
- (id)initWithShape:(Shape*)shape rotation:(float)rotation position:(CGPoint)position 
{ 
    self = [super init]; 
    if (self) { 
     _position=position; 
     _shape=shape; 
     _rotation=MAX(0, MIN(rotation, 360)); 
     _color=nil; 
     _shapePath=CGPathCreateMutable(); 


     CGPathAddArc(_shapePath, NULL, _position.x, _position.y, _shape.radius, 2*M_PI, 0, YES); 
     CGPathCloseSubpath(_shapePath); 
    } 
    return self; 
} 

// in the processing class 


-(void)recursiveTest:(ShapeObject*)shapeObject{ 
    if (!CGRectIntersectsRect(CGPathGetBoundingBox(shapeObject.shapePath), contextRect)) { 
     return; 
    } 
    for (ShapeObject *obj in shapeObjects) { 
     if (ccpFuzzyEqual(obj.position, shapeObject.position, 5)) { 
      //break; 
      return; //just return 
     } 
    } 
    [shapeObjects addObject:shapeObjects]; //in front of method calls 
    [self recursiveTest:[[ShapeObject alloc]initWithShape:shapeObject.shape rotation:0 position:findPoint(shapeObject.position, 300, shapeObject.shape.radius*2)]]; 
    [self recursiveTest:[[ShapeObject alloc]initWithShape:shapeObject.shape rotation:0 position:findPoint(shapeObject.position, 240, shapeObject.shape.radius*2)]]; 
    [self recursiveTest:[[ShapeObject alloc]initWithShape:shapeObject.shape rotation:0 position:findPoint(shapeObject.position, 60, shapeObject.shape.radius*2)]]; 
    [self recursiveTest:[[ShapeObject alloc]initWithShape:shapeObject.shape rotation:0 position:findPoint(shapeObject.position, 120, shapeObject.shape.radius*2)]]; 
    [shapeObjects addObject:shapeObjects]; 

} 

La trace de la pile: enter image description here

Après ma logique, il devrait fonctionner comme ceci: vérifiez s'il est hors limites & s'il est déjà ajouté dans le tableau. Si ce n'est pas le cas, appelez les voisins jusqu'à ce que tous les objets de forme soient dans le tableau et que l'image entière soit traversée.

Je fais tout cela dans un thread d'arrière-plan, mais dès que je commence la fonction i obtenir le code EXC_BAD_ACCESS 2.

Après un coup d'oeil j'ai découvert que le code 2 est quelque chose lié avec des pointeurs.

Apparemment, le problème se produit lorsque je crée le chemin en interne, mais je ne comprends pas pourquoi il devrait, car il n'y a pas de pointeur, juste un simple CreateMutablePath, faire le chemin réel de forme, position et rotation et fermer le chemin. C'est tout.

Aussi, ce n'est pas une fuite de mémoire, je suis en train de tester sur mon mac dans le simulateur et j'ai assez de mémoire libre pour tous les objets possibles. Le problème est ailleurs.

+0

Je voudrais vraiment voir la définition de 'ShapeObject'. Comment 'path' est-il stocké là? – Sulthan

+0

Juste pour que nous soyons clairs ici: 'il n'y a pas de pointeur ici, juste un simple CreateMutablePath' -' CGPathRef' et d'autres objets Core Foundation sont aussi des pointeurs. Par exemple. 'CGPathRef' est défini comme' typedef const struct CGPath * CGPathRef; ' – Mar0ux

+0

@Sulthan Eh bien, ils sont toutes les propriétés – skytz

Répondre

3

Il est clair à partir de la trace de la pile que votre récursivité est trop profonde pour la pile. Même s'il y a beaucoup de RAM disponible, la pile est limitée. La taille maximale de la pile est un peu floue mais je pense qu'elle ne peut pas dépasser 1 Mo.

+0

Je ne vois que 38 images répertoriées ... qui pourraient généralement tenir dans la pile ... Je pense que c'est un hareng rouge ... ou au moins pourrait être ... ne peut pas voir assez –

+0

il y a en fait environ 1000 images ... mais il y avait aussi un problème avec le code lui-même (d'abord l'objet add devrait être devant les prochains appels de niveau, et ensuite à la place du break, return, ... juste return). Mais oui ... la pile n'est pas assez grande pour une méthode récursive de ce type, j'ai besoin de faire quelque chose de linéaire. Des idées? – skytz

+0

Vous devez trouver un moyen de limiter la récursivité, peut-être que vos critères de fin de récursion ne s'arrêtent pas assez tôt. – ahwulf

Questions connexes