2011-08-18 1 views
4

J'ai une structure de données que je voulais énumérer. J'ai essayé de mettre en œuvre NSFastEnumerator de mon objet comme suit:Implémentation de NSFastEnumerator: EXC_BAD_ACCESS lors de l'itération avec pour ... dans

- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state 
            objects:(__unsafe_unretained id [])buffer 
            count:(NSUInteger)len { 

    NSUInteger c = 0; 
    while (c < len) { 
     id obj = [self objectAtIndex:state->state]; 
     if (obj == nil) break; 
     buffer[c] = obj; 
     c++; 
     state->state++; 
    } 
    state->itemsPtr = buffer; 
    state->mutationsPtr = nil; 
    return c; 
} 

Si je objectAtIndex directement, mon objet fonctionne correctement. Je reçois un zéro quand l'indice n'existe pas. Mais quand je puis utiliser la boucle for:

for (Pin *pin in coll) { ... } 

le code passe par l'amende de fonction ci-dessus et remplit état avec ce qui semble être des valeurs valides et renvoie le nombre d'objets, puis je reçois un échec de EXC_BAD_ACCESS au pour l'énoncé lui-même.

Qu'est-ce que je fais mal dans cette mise en œuvre?

Répondre

1

Je suppose que vous utilisez ARC. Le problème est peut-être que le buffer est un tableau d'objets __unsafe_unretained, donc ARC peut être trop relâcher. Mais à quoi ressemble votre méthode objectAtIndex:? Cela ne devrait pas poser de problème si vous renvoyez des objets dont la durée de vie est garantie au moins aussi longtemps que votre objet lui-même.

+0

Ma objectAtIndex: méthode est supportée par un NSMutableArray dessous, et toute la gestion de la mémoire est gérée par le réseau. La signature de la méthode est générée par XCode lui-même, donc je suppose que c'est correct, mais je ne sais pas avec certitude. – Monopol

+0

Oui, je pense que c'est correct, je le vois dans mes fichiers d'en-tête. Si vous utilisez un NSMutableArray je ne peux pas imaginer pourquoi ce serait un problème. Je recommande de demander sur http://devforums.apple.com. – jtbandes

0

Au lieu de:

id obj = [self objectAtIndex:state->state]; 

utilisation

__unsafe_unretained id = [self objectAtIndex:state->state]; 
2

Je viens d'avoir un des problèmes similaires, et après avoir examiné de plus près Apple FastEnumerationSample, cette partie (que j'avais oublié) sauté sur moi:

// We are not tracking mutations, so we'll set state->mutationsPtr to point into one of our extra values, 
// since these values are not otherwise used by the protocol. 
// If your class was mutable, you may choose to use an internal variable that is updated when the class is mutated. 
// state->mutationsPtr MUST NOT be NULL. 
state->mutationsPtr = &state->extra[0]; 

L'important étant: state->mutationsPtrNE DOIT PAS être NULL. Je viens d'utiliser la ligne d'exemple fournie et cela a fonctionné comme un charme!

Questions connexes