__strong and __weak keyword placement - Objective-C

3.9k views Asked by At

The compiler seems to have no problem with the two following declarations:

NSObject * __weak weakThing;
__weak NSObject *anotherWeakThing;

Is there a difference between the two? Is the behavior like the const keyword?

I ask because Xcode's warning generally suggest ...

SomeDataType * __weak / __strong

... when you've goofed something up. So I've tried to follow this pattern, but wondered if there was a difference at all.

2

There are 2 answers

0
BJ Homer On BEST ANSWER

No, there is no difference. With the const keyword, there are multiple things it could apply to in a declaration; it could apply to the pointer, or it could apply to the value being pointed to.

Ownership qualifiers only make sense on pointers to objects. The object itself can't be "strong" or "weak"; it's the pointer to the object that is strong or weak. ARC only makes sense when applied directly to pointer-to-object types, and affects how that pointer's lifetime will affect the lifetime of the object.

Given that there is never any ambiguity about what the ownership qualifier could apply to, the ARC specification allows placement of the ownership qualifier anywhere in the definition of the pointer-to-object. Both of your examples are equally valid. Likewise, all of the following mean the same thing:

NSError * __autoreleasing * someObject;
NSError __autoreleasing ** someObject;
__autoreleasing NSError ** someObject;

Note that the compiler complains about this one, though:

NSError ** __autoreleasing someObject;

This is because you've moved beyond the definition of the pointer-to-object. You could parse that one as (NSError *)* __autoreleasing someObject;. By the time you get to the second *, you've already defined the type of the pointer, so __autoreleasing doesn't make any sense. Anywhere within the definition of the pointer type is fine, but once you move onto the pointer-to-pointer type, then you're referring to something else, and it no longer makes sense.

0
marc hoffman On

There is a difference if you have

 __weak NSObject *someWeakThing, *someSupposedlyButNotReallyWeakThing;

because the __weak will only confusingly apply to the first variable. (this is a similar mistake to the rookie

NSObject* one, two;

which of course won't work as "expected", either).