Should properties be atomic in NSURLConnectionDataDelegate (NSURLConnectionDelegate) when there are more concurrent connections and properties are accessed by methods being called when connection reaches particular state?
There is no access from other threads to those properties invoked by me.
NSURLConnection's concurrency is run-loop-based, so as long as all the connections for which your object is a delegate are started from the same run loop, you shouldn't need to worry about concurrency in your delegate. If you start multiple connections scheduled on different run loops, then yes, you would need to protect the private state of your delegate objects. Atomic properties are rarely sufficient for this.
In short, you either don't need to worry about this, or atomic properties are unlikely to help. One easy option would be to have all your delegate methods dispatch_async their work to a private serial GCD queue.
Related
Are the instance methods on Microsoft.Azure.Devices.Client.DeviceClient thread-safe? For example, is it safe to have a single instance of DeviceClient, and execute its methods concurrently from multiple threads?
Our current code base makes multiple concurrent calls to UploadToBlobAsync(), UpdateReportedPropertiesAsync(), and SendEventAsync(), all on the same instance. The documentation does not mention thread-safety at all, but I would like to confirm if the methods are thread-safe or not before reworking our current code base to manually prevent concurrent access to the instance methods.
Yes, DeviceClient is thread-safe, according to https://github.com/Azure/azure-iot-sdk-csharp/issues/1613. So you can safely call any instance methods in parallel using just one instance of DeviceClient.
I have an object with a property:
#interface Car
#property(strong) NSLicensePlate *licensePlate;
#end
I use the property in a method:
- (void) doSomething {
[_licensePlate frobnicate];
}
And the property value can be changed in another method:
- (void) doSomethingElse {
[self setLicensePlate:[_licensePlateDealer cleanLicensePlate]];
}
Now, if the -doSomethingElse method is called from another thread while I access the license plate property using the instance variable (as seen in the -doSomething method), is it possible to get a segfault?
Is it possible that the -setLicensePlate setter releases the value stored in _licensePlate right before I call -frobnicate on it and before a new valid value is assigned? And would it help to call [self licensePlate] instead of using _licensePlate directly?
If you want to enjoy the atomic behavior (which is the default behavior that you get because you didn't specify the nonatomic qualifier) of this property, you must use the getter (self.licensePlate or [self licensePlate]), not use the ivar (_licensePlate).
In general, it's usually prudent to use the getters and setters everywhere except (a) the init method; and (b) and custom accessor methods. The overhead is negligible and you avoid spectrum of potential problems ranging from atomicity, memory semantics, KVO, future-proofing code in case you customize accessor methods at some future date, etc.
But, assuming you access your property only through the accessor methods (the getters and setters), the atomic qualifier, as described by Programming with Objective-C: Encapsulating Data ensures that the pointer, itself, that you are retrieving/setting is will not be corrupted by another thread:
[Atomic] means that the synthesized accessors ensure that a value is always fully retrieved by the getter method or fully set via the setter method, even if the accessors are called simultaneously from different threads.
In answer to your question, if the other thread changes the licensePlate property, while the frobnicate method is running on the other thread, that original object will not be released until that method returns.
But to be clear, the atomic qualifier does not ensure thread safety. As the above guide goes on to warn us:
Note: Property atomicity is not synonymous with an object’s thread safety.
Consider an XYZPerson object in which both a person’s first and last names are changed using atomic accessors from one thread. If another thread accesses both names at the same time, the atomic getter methods will return complete strings (without crashing), but there’s no guarantee that those values will be the right names relative to each other. If the first name is accessed before the change, but the last name is accessed after the change, you’ll end up with an inconsistent, mismatched pair of names.
This example is quite simple, but the problem of thread safety becomes much more complex when considered across a network of related objects. Thread safety is covered in more detail in Concurrency Programming Guide.
So, it might be thread-safe to use frobnicate on one thread while doing other stuff on another thread, but it also might not. It depends upon all the different things that can be done with this license plate object. Because the protections offered by atomic are so minimalist, we frequently will employ some synchronization (via GCD serial queue or GCD reader-writer pattern, or via any of the synchronization methods outlined in the Threading Programming Guide: Synchronization such as locks) to coordinate interaction from different threads.
When you define properties, you can set them as atomic (the default) or nonatomic.
Since you're using the atomic default, you should be fine about thread safety, but that also depends on how you implemented frobnicate, setLicensePlate: and cleanLicensePlate.
Please refer to this question to get more details about atomic vs nonatomic: What's the difference between the atomic and nonatomic attributes?
I'm going to distill a very common situation to a general form. Say I'm building some library object that goes off, does some async work, then calls back to a delegate method when it's done. Now, also say for some arbitrary reason that I can't use ARC or blocks for the callback. It's old-fashioned. Let's call this object the Worker.
Now say there are several other classes across various apps that don't know anything about Worker aside from its public interface. They use the Workers to their own ends. Let's call these classes the Consumers.
Say Worker makes delegate callbacks like this:
// "Private" method called internally when work is done.
- (void)somethingFinished
{
[self.delegate workerDidFinish];
[self someTask];
}
And say some particular Consumer handles the callback like this:
- (void)workerDidFinish
{
// Assume "worker" is a retain property to a Worker
// instance that we previously created and began working,
// and that it's also the sender of the message.
self.worker = nil;
// Other code...
}
Now, if nothing else has retained that particular Worker instance, we're in trouble. The Worker will be deallocated, then control will return to its -somethingFinished method, where it will then send -someTask to reclaimed or garbage memory, and likely crash. Nobody has blatantly violated any memory management rules.
I'm not asking for a technical solution here. I know several options. I'm wondering on whom the burden of responsibility for the fix falls. Should I, as the component designer, implement Worker's -somethingFinished method such that the Worker's lifespan is extended for the duration of the method with something like [[self retain] autorelease] at the beginning? Or should I, as the consumer of the component be aware that I might be blowing away an object halfway through an instance method, and wait until later to release it?
This question's answers all seem to indicate that releasing the object from the callback is a Bad Idea. Unfortunately, there's a lot of distracting information in that question about how exactly the Worker (CLLocationManager in this instance) is passed to the delegate that I've intentionally avoided here. This question is suffering the same scenario, and offers the other solution.
Personally, I can't see how the Consumer could be held responsible. It's not breaking any memory management rules, and is politely consuming the Worker's public interface. It's simply releasing an instance when it's no longer needed. But on the other hand, does that mean that any object that could possibly, somehow, be deallocated mid-method needs to artificially extend its own lifespan? Delegate methods, after all, aren't the only way a message sender could end up deallocated in the middle of a method.
So ultimately, who is responsible for the fix? Worker? Consumer? Can it be determined canonically?
I think the burden is on the Worker in this example. The problem I see is that the Worker object is doing something internally after telling its Consumer that its work has finished. The Worker only exists for the sake of the Consumer so if the Consumer's objective is met why is Worker still doing something that has no value to the Consumer? If there are internal tasks that need to be completed after the 'consumable' work is done then those tasks are not suitably placed in an instance of the Worker object, but probably should be done by another internal object owned by a less volatile library class that won't be dealloc'd by actions of the Consumer.
When the delegate gets notified, should start observing the worker and release it only when somethingFinushed method is terminated.
My question is very straight forward: is the delegate design pattern in iOS truly multithreaded? Meaning is there actual parallel execution going on or is it still all running on the main thread?
It depends if you call the delegate methods on a different thread or not. In general, delegate methods are called on the same thread after a certain event. In short terms, threading has nothing to do with delegation and from my experience Apple always posts the delegate callbacks methods to the main thread (however, you can choose not to, but things can become nasty if you do).
Delegation has nothing to do with threading. Delegation is about allowing one object to make decisions on behalf of another. It is normally done in a single-threaded manner, since there's little to be gained from spawning a thread every time you want to ask a delegate something and it would complicate the design considerably.
My question, in brief: Is there any way to make mutable collection KVO accessors thread-safe with the same lock that the #synthesized methods are locked?
Explanation: I have a controller class which contains a collection (NSMutableArray) of Post objects. These objects are downloaded from a website, and thus the collection changes from time to time. I would like to be able to use key-value observing to observe the array, so that I can keep my interface updated.
My controller has a posts property, declared as follows:
#property (retain) NSMutableArray *posts;
If I call #synthesize in my .m file, it will create the -(NSMutableArray *)posts and -(void)setPosts:(NSMutableArray *)obj methods for me. Further, they will be protected by a lock such that two threads cannot stomp on each other while setting (or getting) the value.
However, in order to be key-value coding compliant for a mutable ordered collection, there are a few other methods I need to implement. Specifically, I need to implement at least the following:
-insertObject:inPostsAtIndex:
-removeObjectFromPostsAtIndex:
However, since the posts are downloaded asynchronously, I would like to be able to insert new posts into the array on a background thread as well. This means that access needs to be thread-safe.
So, my question. Is there any way to make those accessors thread-safe with the same lock that the #synthesized methods are locked? Or do I have to resort to specifying the setPosts: and posts methods myself in order to guarantee full atomicity across all accessors?
The Objective-C docs at developer.apple.com[1] don't state that there's a way to use the same lock for your explicitly defined functions as gets used for your #synthesized functions. In that case I'd say that to be completely safe it would be better to fully define your own functions to be sure they all use the same lock.
You may be able to use the debugger to determine the name of the lock that gets used for your #synthesized functions, but that's not something I'd rely on.
You probably don't really want to do this. If you do succeed, KVO-notifications will be received on the same thread that makes the change, and if it's a background thread, will be unsuitable for updating the UI.
Instead, why not have your background thread update the property using the main thread? Then you don't even need the property to be atomic.