Re: How to update UI from a background thread
Re: How to update UI from a background thread
- Subject: Re: How to update UI from a background thread
- From: Dave <email@hidden>
- Date: Thu, 22 Sep 2016 13:20:16 +0100
Hi Jens,
There is definitely something fishy going on, I’ll explain the process and how I am handling it. There is probably a much better way of doing it and if so I’m happy to redesign it.
In order to kick off a Network an third part App needs to be run which starts up a process that “looks” for available networks. When it finds one it makes it available for my App.
My App needs to grab the state of a Network which is handling by a third party package. The only way in which to check if a network is available is to attempt to create a Network Object (e.g. myNetwork [[Network alloc] initWithXXXXX];). If it returns nil, then the Network was not available. So the only way to ensure a Network is available is to Poll it.
My App does this:
User Clicks the “Connect” button, this launches the Third Party App and then runs an AppleScript to tell it to start looking for Network.
The Button handler in my App then starts a timer that Polls the Network every 0.10 seconds. The Timer handler basically does a Alloc/Init and if it gets nil restarts the timer to try again a bit later on. If it gets non nil, then it sends a “NetworkConnected” notification.
The Button Handler then calls “waitForNetworkConnection” which checks if there is a valid Network stored in a “connectedNetworksDictionary which is a property of the WindowController.
If it is not in the dictionary it calls itself back after a delay. So the button handler will return, but the “waitForNetworkConnection” will be called
The “NetworkConnected” notification handler then the stores the Network in the “connectedNetworksDictionary” property.
Accesses to the “connectedNetworksDictionary” are protected in an @synchronised block.
I noticed that the UI stops responding while stepping through the following code.
//** THIS STATUS MESSAGE IS SEEN
myNetworkStatusString = [[NSString alloc] initWithFormat:@"Executing Script %@ for Target Network: %@",myNetworkleScriptFilePath,theNetworkConfigInfo.pNetworkConfigInternalID];
[self updateUIStatusWithInfoMessage:myNetworkStatusString];
myNetworkleScriptSourceString = [[NSString alloc] initWithContentsOfFile:myNetworkleScriptFilePath encoding:NSUTF8StringEncoding error:&myErrorInfo];
if (myErrorInfo != nil)
{
myNetworkStatusString = [[NSString alloc] initWithFormat:@"Script Compile Error %@ for Target Network: %@",myNetworkleScriptFilePath,theNetworkConfigInfo.pNetworkConfigInternalID];
[self updateUIStatusWithErrorMessage:myNetworkStatusString];
return NO;
}
myNetworkleScript = [[NSNetworkleScript alloc] initWithSource:myNetworkleScriptSourceString];
[myNetworkleScript executeAndReturnError:&myErrorDictionary];
if (myErrorDictionary != nil)
{
myNetworkStatusString = [[NSString alloc] initWithFormat:@"Script Execution Error %@ for Target Network: %@",myNetworkleScriptFilePath,theNetworkConfigInfo.pNetworkConfigInternalID];
[self updateUIStatusWithErrorMessage:myNetworkStatusString];
return NO;
}
//** UI STOPS UPDATING HERE
myNetworkStatusString = [[NSString alloc] initWithFormat:@"Script Complete %@ for Target Network: %@",myNetworkleScriptFilePath,theNetworkConfigInfo.pNetworkConfigInternalID];
[self updateUIStatusWithInfoMessage:myNetworkStatusString];
So I’m wondering if it is something to do with the AppleScript handling? The Script works ok if I run it from the Script Editor and it compiles and runs ok.
Any help on this would be greatly appreciated.
All the Best
Dave
> On 21 Sep 2016, at 17:20, Dave <email@hidden> wrote:
>
> Hi,
>
> This doesn’t work probably because the Class is that is calling back the delegate method that updates the Scroll View is also being run on the main thread. Sorry I should have said this earlier. I tried updating the UI on a background thread and it seemed to work BUT I got warning message from CALayer or maybe CATransaction and I think it caused the App to hang.
>
> The time consuming method I am calling is in a third party library and it must be called in the main thread.
>
> All the Best
> Dave
>
>> On 21 Sep 2016, at 17:01, Sandor Szatmari <email@hidden> wrote:
>>
>> In general, one simple form is:
>>
>> dispatch_async( dispatch_get_main_queue(), ^{
>> // do UI updates on the main thread.
>> });
>>
>> This can also be done with NSOperationQueue:
>>
>> [[NSOperationQueue mainQueue] addOperationWithBlock:^{
>> // do UI updates on main thread.
>> }];
>>
>> Sandor Szatmari
>>
>> On Sep 21, 2016, at 11:40, Dave <email@hidden <mailto:email@hidden>> wrote:
>>
>>> Hi All,
>>>
>>> How can I update my UI from a background thread?
>>>
>>> I have a method that does a LOT of intense processing, it calls a delegate method in my Window Controller which appends it to a Logging Scroll View, however nothing shows up in the Scroll View although it NSLog’s the string ok.
>>>
>>> Firstly is it ok to do this? When I tried it I got a CALayer error reported in the NSLog output.
>>>
>>> All the Best
>>> Dave
>>>
>>>
>>> _______________________________________________
>>>
>>> Cocoa-dev mailing list (email@hidden <mailto: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 <http://lists.apple.com/>
>>>
>>> Help/Unsubscribe/Update your Subscription:
>>>
>>> This email sent to email@hidden <mailto:email@hidden>
> _______________________________________________
>
> 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
_______________________________________________
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