If I have a swift Actor...
@objc public actor SomeActor: NSObject, SomeProtocol { ... }
...and I want to use it as an ivar in objc code, does it need to be listed as atomic to retain it's thread safety, or is it more performant to call it nonatomic?
Also, do I need to be referencing it with a getter to preserve its thread safety, or can I call it directly?
#import <ThisProject/ThisProject-Swift.h>
@interface SomeClass () <SomeId>
@property (strong, atomic, readwrite) SomeActor *someActor;
@end
...
[SomeOtherClass someMethod:someActor];
vs
@interface SomeClass () <SomeId>
@property (strong, nonatomic, readwrite) SomeActor *someActor;
@end
...
[SomeOtherClass someMethod:_someActor];
While Alexander answered your question (and you should feel free to accept his answer; +1), I offer a few clarifying observations:
What is the purpose of
atomic?The
atomicqualifier on the property just dictates how Objective-C synthesized accessors handle the pointer to the actor and has nothing to with the actor’s internal behaviors. As the documentation says,atomic“means that the synthesized accessors ensure that a value [the pointer in this case] 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.”The
atomickeyword simply ensures that the synthesized accessor methods atomically fetch and store the pointer address, itself. It has no bearing on the internal thread-safety (or lack thereof) of the object to which it points.Should one use
atomicornonatomic?In practice,
atomicoften introduces (admittedly negligible) overhead with limited benefit. Like Alexander, I almost always usenonatomic. If the Objective-C code has thread-safety issues, one often needs a higher-level of synchronization, rendering theatomicnature to the pointer largely moot. It depends the Objective-C code (which is not really relevant to the immediate question).But, as Alexander pointed out, whether you mark the property as
atomicornonatomicis irrelevant to the fact that you are pointing to anactoror some otherclass.Should you use the property getter,
self.someActor, or access the backing ivar,_someActor?You did not explicitly ask this question, but one of your examples, you refer to
someActor(which I presume means you intended to use the getter, though given the absence of eitherself.or the leading underscore, it is not entirely clear) and in the other,_someActor(the property’s backing ivar).As Programming with Objective-C says, “… it’s best practice for an object to access its own properties using accessor methods or dot syntax.” The two common exceptions to this rule are (a) in
init; and (b) in manually implemented getters/setters, if any.So, in short, I would generally use
self.someActorand not_someActor.Please note, I belabor this accessor vs. ivar distinction because the
atomic/nonatomiconly dictates the nature of the synthesized accessor methods. It has no effect on direct interaction via the ivar. Thus, anatomicivar is a bit of a non-sequitur, as directly interacting with the ivar bypasses the accessors and their synthesized behaviors (includingatomic), too.Bottom line, feel free to use
nonatomic. And if you are trying to ensure that the Objective-C code, itself, is thread-safe, we would need to see any relevant code, but, generally, merely making the propertyatomicwould be insufficient. The fact that you are dealing with anactorhas no meaningful impact on the choice ofatomicornonatomic.For folks looking for a description of
actorinteroperability with Objective-C, see SE-0297 – Concurrency Interoperability with Objective-C.