Question

sizeWithFont écrasé en multithread, voici l'info de débogage:

1 0x00a0df8e in icu::RuleBasedBreakIterator::handleNext
2 0x00a0daff in icu::RuleBasedBreakIterator::next
3 0x00a0d174 in icu::RuleBasedBreakIterator::following
4 0x35879719 in WebCore::nextBreakablePosition
5 0x3587842a in -[NSString(WebStringDrawing) _web_drawInRect:withFont:ellipsis:alignment:lineSpacing:includeEmoji:measureOnly:]
6 0x35877da3 in -[NSString(WebStringDrawing) _web_sizeInRect:withFont:ellipsis:lineSpacing:]
7 0x3090d238 in -[NSString(UIStringDrawing) sizeWithFont:constrainedToSize:lineBreakMode:lineSpacing:]
8 0x3090cee3 in -[NSString(UIStringDrawing) sizeWithFont:constrainedToSize:lineBreakMode:]

maintenant je résoudre l'erreur en utilisant un objet NSLock, avant d'utiliser cette fonction, je verrouiller cet objet, et après que le déverrouiller

mais je pense qu'il doit y avoir une solution plus mieux!

et j'ai trouvé cette erreur est apparue que lorsque l'objet NSString pour cette fonction sur les deux deux threads sont texte multi-lignes

Était-ce utile?

La solution

En règle générale, vous ne devriez pas appeler des méthodes UIKit [1] à partir d'un thread séparé. Peu importe si vous prenez des serrures, c'est un non-starter.

Lorsque vous utilisez des applications multi-thread, vous devez vous assurer que tout code qui touche tout UIKit objets sur le fil exécute principal. Ceci est obtenu en utilisant le performSelectorOnMainThread: withObject: waitUntilDone: procédé qui invoque le sélecteur donné sur le fil conducteur:

http://developer.apple.com/iphone/library/documentation/cocoa/reference/foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ / INSTM / NSObject / performSelectorOnMainThread: withObject: waitUntilDone :

Ou dans MonoTouch: foo.InvokeOnMainThread (délégué {your_code_here});

[1] Avec iOS 4.0, la règle est assouplie pour une poignée d'API.

Autres conseils

  • Mise en forme, s'il vous plaît.

  • « Résolution » un problème multithread en plaçant des verrous au hasard autour des objets est jamais la bonne réponse. Jamais. Multi-threading nécessite une conception systémique de votre application.

  • Si une serrure ne « régler » le problème, montrant ce que vous avez verrouillé et comment il est essentiel d'évaluer la situation.

  • Quelques autres symptômes seraient utiles. Code, en particulier. Code vos questions est très utile.

Compte tenu de l'absence de preuves, je parierais que votre mutent une chaîne sur un fil tout en essayant de saisir la taille sur un autre. Ou l'objet est libéré un fil tout en utilisant une autre. Ou vous manipulez un objet à partir d'un fil secondaire qui est pas thread-safe.

Je pense performSelectorOnMainThread: withObject: waitUntilDone: est correct,

Avant, j'utiliser une opération pour calculer la taille du texte, Et l'utilisation waitUntilAllOperationsAreFinished dans le thread principal pour attendre le retour de l'opération,
Mais si je l'utilise aussi performSelectorOnMainThread: withObject: waitUntilDone dans l'opération, et définissez le paramètre waitUntilDone Oui (Parce que je dois le résultat)
Le fil conducteur sera stucked

Alors maintenant, je supprimer waitUntilAllOperationsAreFinished, et utiliser un objet asynchrone pour assurer l'opération ne commencera pas avant le précédent arrêté

                    [md removeAllObjects];
                    [md setObject:subString forKey:@"text"];
                    [md setObject:[NSNumber numberWithInt:view_w ] forKey:@"width"];
                    [md setObject:[NSNumber numberWithInt:height_left + font_h ] forKey:@"height"];
                    [self  performSelectorOnMainThread:
                     @selector(calculateTextRegion:)
                                            withObject:md
                                         waitUntilDone:YES];
                    CGSize stringSize = textRegion;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top