2011-07-23 6 views
3

la méthode enumerateAttributesInRange obtient un bloc de code et l'exécute pour chaque attribut dans NSAttributedStringNSAttributedString - enumerateAttributesInRange provoque un crash?

  • -t-il appeler le bock de manière asynchrone?

Lorsque la méthode suivante est appelée deux fois de suite vraiment rapide 1 après la othr mon application se fige, je me demande de c'est parce que enumerateAttributesInRange dirige le bloc de code en mode asynchrone, donc 2 fils tentent de modifier mon AttributedString en même temps.

- (void) doSomething 
{ 
    //following line works fine 
    [self doSomethingwithAttributedString]; 

    //following line works fine 
    [self doSomethingwithAttributedString]; 
    [self performSelector:@selector(doSomethingwithAttributedString) withObject:nil afterDelay:1]; 

    //following crashes 
    [self doSomethingwithAttributedString]; 
    [self doSomethingwithAttributedString]; 
} 

- (void)doSomethingwithAttributedString 
{ 
    [self.attributedString enumerateAttributesInRange:_selectedRange options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock: 
^(NSDictionary *attributes, NSRange range, BOOL *stop) { 

      // Here I modify the dictionary and add it back to my attributedString 
}]; 
} 

Répondre

5

Vous modifiez la chaîne attribuée pendant son énumération. Je parie que cela complique énormément l'énumérateur, puisque la chaîne attribuée sur laquelle il travaille n'est pas dans l'état où il était quand il a commencé à énumérer. Dans le bloc, seulement collecter les attributs, par ex. dans un dictionnaire ou un tableau, mais modifiez-les et appliquez-les à la chaîne par la suite, c'est-à-dire une fois l'énumération terminée. En d'autres termes: ne mettez pas de code qui modifie la chaîne attribuée dans le bloc qui est appelé pendant l'énumération. Le docs dit que vous pouvez modifier la chaîne attribuée dans la plage sur laquelle le bloc s'applique, mais ISTM vous devez prendre soin de ne pas sortir. Je ne ferais pas ça.

0

Je suis un peu en retard, mais en ajoutant [self.attributedString beginEditing]; avant et [self.attributedString endEditing]; après semblent résoudre l'accident.

+0

N'oubliez pas non plus de tester la clé du dictionnaire pour un objet nul. – Stuart

Questions connexes