Domanda

sizeWithFont si è schiantato in multithread, questo è l'informazioni di debug:

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:]

ora risolvere l'errore utilizzando un oggetto NSLock, prima di usare questa funzione io bloccare questo oggetto, e dopo che lo sblocco

ma credo che ci deve essere una soluzione più meglio!

e ho trovato questo errore apparso solo quando l'oggetto NSString per questa funzione su entrambi due fili sono linee multiple di testo

È stato utile?

Soluzione

Come regola generale, non si dovrebbe invocare metodi UIKit [1] da un thread separato. Non importa se sta assumendo serrature, questo è un non-starter.

Quando si utilizza applicazioni multi-threaded, è necessario fare in modo che tutto il codice che tocca ogni UIKit oggetti eseguito sul thread principale. Ciò si ottiene utilizzando il performSelectorOnMainThread: withObject: waitUntilDone: metodo che richiama la proposta selettore sul thread principale:

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

O in MonoTouch: foo.InvokeOnMainThread (delegato {your_code_here});

[1] Con iOS 4.0 la regola è rilassato per una manciata di API.

Altri suggerimenti

  • Formattazione, per favore.

  • "Soluzione" un problema multi-threaded, ponendo blocchi casuali intorno agli oggetti non è mai la risposta giusta. Non mai. Multi-threading richiede una progettazione sistemica della vostra applicazione.

  • Se un blocco non "fissare" il problema, mostrando ciò che è stato bloccato e come è fondamentale per valutare la situazione.

  • Alcuni altri sintomi sarebbe utile. Codice, in particolare. Codice nel tuo domande è molto utile.

Data la mancanza di prove, scommetto che il vostro stanno mutando una stringa su un thread durante il tentativo di afferrare la dimensione su un altro. O l'oggetto viene rilasciato su un thread pur utilizzando un altro. Oppure si stanno manipolando un oggetto da un thread secondario che non è thread-safe.

Credo performSelectorOnMainThread: withObject: waitUntilDone: è corretto,

Prima, io uso un'operazione per calcolare la dimensione del testo, E l'uso waitUntilAllOperationsAreFinished nel thread principale per attendere il ritorno del funzionamento,
Ma se io uso anche performSelectorOnMainThread: withObject: waitUntilDone nel funzionamento, e impostare il parametro waitUntilDone su Yes (Perché ho bisogno del risultato)
Il filo conduttore sarà stucked

Così ora tolgo waitUntilAllOperationsAreFinished, e utilizzare un oggetto asincrono per garantire l'operazione non comincerà fino a quando il precedente fermato

                    [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;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top