Re: dispatch_sync(dispatch_get_main_queue() UI weirdness
Re: dispatch_sync(dispatch_get_main_queue() UI weirdness
- Subject: Re: dispatch_sync(dispatch_get_main_queue() UI weirdness
- From: Doug Hill <email@hidden>
- Date: Fri, 05 Sep 2014 14:27:59 -0700
My take on this is that you shouldn’t be blocking an AppKit callback (applicationDidFinishLaunching:). I can’t say definitively if this particular callback is problematic. But I’ve had problems like this in past where the delegate is called on the main thread and the delegate doing a blocking call on the main queue will block much of AppKit. I’ve basically come to the conclusion that you shouldn’t do it.
One technique I use to handle this is to wrap the dispatch_sync with a dispatch_async, such as:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^{
dispatch_sync(dispatch_get_main_queue(),
^{
// Do your NSOpenPanel or other UI
});
});
This way, you can still execute your UI code synchronously on the main queue but you don’t block AppKit in your callback.
Good luck!
Doug Hill
On Sep 5, 2014, at 1:49 PM, Sandy McGuffog <email@hidden> wrote:
> Difficult to know exactly what's happening in your situation, but I’d be inclined to try something like:
>
> dispatch_time_t duration = dispatch_walltime(DISPATCH_TIME_NOW, offset_nsec);
>
> dispatch_after(duration, dispatch_get_main_queue(), ^{
>
> });
>
> where offset_nsec is long enough to allow the app to complete it’s start-up process
>
> Sandy
>
> On Sep 5, 2014, at 10:31 PM, Jonathan Guy <email@hidden> wrote:
>
>> I’m using a third party c library that requires registering a callback which gets called if the operation encounters an invalid server certificate (should i accept or reject the cert). The callback needs to return yes or no, which I need to get via a UI prompt so the prompt needs to block so I can return appropriately from the callback. So my initial thoughts are “present the cert in a modal window”. So I put the cert in a SFCertificateView in a scroll view and present it in a modal window but it could not be scrolled up and down which was the initial problem. I also tried the SFCertificatePanel with the same problem. After testing I found I couldn’t scroll any scroll view so I knocked up that small bit of code to show as an example. I tried using performSelectorOnMainThread and waiting until completion and this funnily enough works fine in terms of absolutely no UI weirdness but I can’t get a return value from that plus there were other issues.
>> There could be any number of operations running concurrently and any one could require validation at any time.
>>
>> The callback is basically structured like this
>>
>> __block BOOL accept;
>>
>> if ([NSThread isMainThread]) {
>> accept = [[Controller sharedController] shouldIAccept:certInfo];
>> }
>> else {
>> dispatch_sync(dispatch_get_main_queue(), ^{
>> accept = [[Controller sharedController] shouldIAccept:certInfo];
>> // This is where UI starts playing up when the controller shows the cert
>> });
>> }
>>
>> return accept;
>>
>> So the shouldIAccept method needs to block hence runModal. I also just threw the window up and created my own modal loop but same problem.
>>
>> On 5 Sep 2014, at 19:59, Jens Alfke <email@hidden> wrote:
>>
>>>
>>>> On Sep 5, 2014, at 11:44 AM, Jonathan Guy <email@hidden> wrote:
>>>>
>>>> when the NSOpenPanel opens all kinds of weirdness is going on. The scroll views scroll very erratically if at all and the directories don't list properly.
>>>
>>> Well, you've blocked one of the threads that services the global dispatch queue — it's stuck in a dispatch_sync call that won't return until the user dismisses the open panel. I don't know exactly what kinds of problems blocking the queue will cause, but it's definitely not a good idea. (The problems you report sound more severe than what I would guess would happen, but I definitely don't know how concurrent dispatch queues are implemented.)
>>>
>>> You should rewrite your code to use dispatch_async instead. Then when the modal session completes, call back to the global dispatch queue to finish running your code.
>>>
>>> (And the whole scenario you're giving sounds like bad UI design — your code shouldn't suddenly pop up a modal panel just because you "need a file from the user". The user should be in control of tasks like opening files. But you may have created an unrealistic scenario just as an example…)
>>>
>>> —Jens
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden