Reputation: 1362
Previously I've been able to use the following code to place attributed text into an NSTextView field
[[self->content textStorage] appendAttributedString:contentString];
However, upon updating to the Xcode 6 Beta to develop for Yosemetie, what used to work now gives me this error:
2014-08-26 11:06:06.635 JaxWire[59482:1765389] An uncaught exception was raised
2014-08-26 11:06:06.636 JaxWire[59482:1765389] Modifications to the layout engine must not be performed from a background thread.
and a whole much more globety gloop that I don't think has much use.
To give context as to how it works, a user enters text in a field, triggers a method called GO
in the class InterfaceManager
which then runs the following code to spawn a new thread ProcessQuery
in the AppDelegate
class, which is where I am attempting to change the content of NSTextView with an attributed string
[NSThread detachNewThreadSelector:@selector(processQuery:) toTarget:self withObject:query];
It's worth noting that this works if I use a standard string by executing [self->content setString:@"String"];
but when it comes to using an attributed string, it doesn't work.
How would I go about fixing this problem?
Thanks in advance! :)
Upvotes: 0
Views: 1669
Reputation: 7534
it has nothing at all to do with Xcode. You are explicitly asking for this to be done on a background thread by using [NSThread detachNewThreadSelector]
, and as has been pointed out in comments, this is not allowed. You have never been "allowed" to modify the UI from a background thread, but often you could do so without noticeable problems. Yosemite is likely just enforcing this more strictly than previous versions of OS X.
I suppose the reason it works with setString:
is because setString:
probably doesn't immediately call the layout engine and rather the next drawing pass on the main thread does that.
you either have to not detach processQuery
to a background thread, or have processQuery
call appendAttributedString
on the main thread using something like:
[[self->content textStorage] performSelector:@selector(appendAttributedString:) withObject: contentString]
or using GCD dispatch_async()
with the main thread's queue dispatch_get_main_queue()
Upvotes: 1
Reputation: 23624
Try editing the string on the main thread instead:
dispatch_async(dispatch_get_main_queue(), ^()
{
[[self->content textStorage] appendAttributedString:contentString];
});
Upvotes: 2