I've been given the task to clean up some existing Swift code on our project which has just been converted to Swift 3. However, I keep seeing this which looks suspect to me.
OperationQueue().addOperation(someOperation)
Here are the concerns/issues I have...
The queue instance is created and used right there. No reference to it is stored for use elsewhere.
Because of the above, there will only ever be one operation in the queue, so why use the queue at all?
Since no one is holding a reference to the queue, under ARC, shouldn't it be instantly deallocated, and if so, what happens to the now-executing operation itself? Does it get interrupted, aborted or does it still complete?
Anyway, I'm wondering if I'm missing something or am unaware of a 'feature' of NSOperationQueue and NSOperations that make this code make sense. Can anyone shed light on this, or do you agree this is bad practice?
I've seen this pattern too. I think it works like NSURLConnection: the NSOperationQueue "knows" it has a pending operation and doesn't allow itself to go out of existence immediately. Also keep in mind that an NSOperationQueue isn't really a "thing"; it's a kind of front for an underlying dispatch queue.
It makes a certain sense to use this pattern in situations where there is no reasonable place to store a reference to the queue. And you can use it to powerful effect, as in this example where the operation has dependencies and thus is not executed until all the dependencies are.
Personally, however, if I'm not taking advantage of NSOperation features of that sort, I'd be more inclined to use GCD directly.
(As to your middle point, it would not make sense to execute on the main thread, because what if the operation is lengthy? You'd be blocking the main thread. However, do note that if all you're trying to say is "do this after everything else", Swift gives you defer.)
Related
While re-reading scala.lan.org's page detailing Future here, I have stumbled up on the following sentence:
In the event that some of the callbacks never complete (e.g. the callback contains an infinite loop), the other callbacks may not be executed at all. In these cases, a potentially blocking callback must use the blocking construct (see below).
Why may the other callbacks not be executed at all? I may install a number of callbacks for a given Future. The thread that completes the Future, may or may not execute the callbacks. But, because one callback is not playing footsie, the rest should not be penalized, I think.
One possibility I can think of is the way ExecutionContext is configured. If it is configured with one thread, then this may happen, but that is a specific behaviour and a not generally expected behaviour.
Am I missing something obvious here?
Callbacks are called within an ExecutionContext that has an eventually limited number of threads - if not by the specific context implementation, then by the underlying operating system and/or hardware itself.
Let's say your system's limit is OS_LIMIT threads. You create OS_LIMIT + 1 callbacks. From those, OS_LIMIT callbacks immediately get a thread each - and none ever terminate.
How can you guarantee that the remaining 1 callback ever gets a thread?
Sure, there could be some detection mechanisms built into the Scala library, but it's not possible in the general case to make an optimal implementation: maybe you want the callback to run for a month.
Instead (and this seems to be the approach in the Scala library), you could provide facilities for handling situations that you, the developer, know are risky. This removes the element of surprise from the system.
Perhaps most importantly - it enables the developer to "bake in" the necessary information about handler/task characteristics directly into his/her program, rather than relying on some obscure piece of language functionality (which may change from version to version).
While I was browsing through the iOS 7 runtime headers, something caught my eye. In the MCNearbyServiceAdvertiser class, part of the Multipeer Connectivity framework, a property called syncQueue is and multiple methods prefixed with sync are defined. Some of the methods both exist in a prefixed and non-prefixed version, such as startAdvertisingPeer and syncStartAdvertisingPeer.
My question is, what would be the purpose of both this property and these prefixed methods, and how are they combined?
(edit: removed the remark that the queue is serial as pointed out by CouchDeveloper, since we cannot know this)
As you know, the implementation is private.
Having a dispatch queue whose name is syncQueue may not mean that this queue is a serial queue. It might be a concurrent queue as well.
We can only have a guess what the startAdvertisingPeer and the "prefixed" version syncStartAdvertisingPeer might mean.
For example, in order to fulfill internal prerequisites startAdvertisingPeer might assume that it is always invoked from an execution context except the syncQueue. That way, it can synchronously dispatch to the syncQueue with invoking syncStartAdvertisingPeer without ending up in a deadlock. On the other hand, syncStartAdvertisingPeer will always assume to execute on the syncQueue, that way guaranteeing concurrency.
But, as stated, we don't know the actual details - it's just a rough guess. Usually, you should read the documentation - and not some private header details to draw a picture in your mind how this class might likely work.
I want to know what is difference between perform selector in backgorund and detachNewThread
They Are identical. as you can see in Documentation section Click Here
performSelectorInBackground:withObject: The effect of calling this method is the same as if you called the detachNewThreadSelector:toTarget:withObject: method of NSThread with the current object, selector, and parameter object as parameters.
performSelectorInBackground:withObject: is easier way rather than NSThread.
However, NSThread can control its priority, stacksize, etc. If you'd like to customize the behavior, I recommend NSThread instead of performSelectorInBackground:withObject:.
I would look at it from a semantic point of view. There is no technical reason to use one or the other.
Use NSThread if you actually "think" of having a thread that "does something"; in particular, it will probably be the most appropiate way of creating a thread if your thread runs some form of event- or messaging loop. In such a case, the "thread object" is really just that; in many cases it's not an "application realm" object with actual application data, as these will be handed over to the thread in some way.
Use the NSObject-based methods if your thread is merely meant to run some single operation in the background. You don't really care about this being a "thread", and the object that you run this on is likely to be the "application realm" object with the data; there's no event- or messageloop to feed it commands from other threads.
Thus, I would base the decision on abstract factors, as in "what looks better in the given context". Having an NSThread "feels" like a more detached entity that is willing to offer services to multiple clients, whereas the NSObject method feels like it's closely attached to the data object that it runs with, and doesn't really deal with anything else unless it's vital to the cause.
I have a processing thread that I use to fill a data buffer. Elsewhere a piece of hardware triggers a callback which reads from this data buffer. The processing thread then kicks in and refills the buffer.
When the buffer fills up I am currently telling the thread to wait by:
while( [self FreeWriteSpace] < mProcessBufferSize && InActive) {
[NSThread sleepForTimeInterval:.0001];
}
However when I profile I am getting a lot of CPU time spent in sleep. Is there a better way to wait? Do I even care if the profiles says time is spent in sleep?
Time spent in sleep is effectively free. In Instruments, look at "running samples" rather than "all samples." But this still isn't an ideal solution.
First, your sleep interval is crazy. Do you really need .1µs granularity? The system almost certainly isn't giving you because the processor isn't that fast. I have to believe you could up this to .1 or .01. But that's still busy-waiting which is not ideal if you can help it.
The better solution is to use an NSCondition. In this thread, wait on the condition, and in your processing thread, trigger the condition when there's room to write.
Do be careful with your naming. Do not name methods with leading caps (that indicates that it's a class name). And avoid accessing ivars directly (InActive) like this. "InActive" is also a very confusing name. Does it mean the system is active (In Active) or not active (inactive). Naming in Objective-C is extremely important. The compiler will not protect you the way it does in C# and C++. Good naming is how you keep your programs working, and many parts of ObjC rely on it.
You may also want to investigate Grand Central Dispatch, which is particularly designed for these kinds of problems. Look at dispatch_async() to run things when new data comes in.
However when I profile I am getting a
lot of CPU time spent in sleep. Is
there a better way to wait? Do I even
care if the profiles says time is
spent in sleep?
Yes -- never, never poll. Polling eats CPU, makes your app less responsive, eats battery, and is an all around waste.
Notify instead.
The easiest way is to use one of the variants of "perform selector on main thread" (see NSThread's documentation). Or dispatch to a queue (including something like dispatch_async(dispatch_get_main_queue(), ^{ ... yo, data be ready ...});).
I'm writing a concurrency application for the iPhone.
I wonder if this code:
while(!conditionBoolean)
{
// do nothing
// until another thread makes this variable true.
}
makeWork();
Is equivalent to the following:
[lock lock]; // this lock is locked by another thread
// causing the current to block until it's unlocked
[lock unlock];
makeWork();
If it's not, what's the difference?
Thank you.
You should prefer the second, the first will produce a tight loop and delay or maybe even prevent the variable being set in the way you want/expect. At the very least you would have to introduce a delay in that loop, a sleep of some kind.
Better still would be to wait on a signalling primitive for the work to complete, which then gets signalled by the other thread - the design is then deterministic, versus depending on a mutex or state variable that some other thread might lock or modify before you get your chance. In general, it's better for a multi-threaded design to be event-driven (push model), not check shared state opportunistically (pull model).
My understanding of mutexes is that the lock can occur in less cycles, so for example it's possible that while you read the conditionboolean to become true, it's possible that another thread could still change it to true while you're reading it, and another goes to false before you read it again. This turns into a race condition, which the mutex locking would hope to avoid. Also this could cause your code not to be the "next in line" if you have numerous functions with a similar while loop.