Appropriateness of assign attribute and -fobj-gc-only
-
According to the Obj-C 2.0 docs:
> assign
> Specifies that the setter uses simple assignment. This is the default.
>
> If your application uses garbage collection, if you want to use
> assign for a property whose class adopts the NSCopying protocol you
> should specify the attribute explicitly rather than simply relying
> on the default—otherwise you will get a compiler warning. (This is
> to reassure the compiler that you really do want to assign the
> value, even though it’s copyable.)
>
But the warning is:
"warning: 'assign' attribute on property 'portName' which implements
'NSCopying' protocol not appropriate with -fobjc-gc-only"
So, is it really inappropriate? It seems very appropriate to assign
the pointer rather than allocate a new object and copy it, especially
for immutable objects.
TIA,
--
Rick -
On Sep 21, 2008, at 14:04, Rick Mann wrote:
> But the warning is:
>
> "warning: 'assign' attribute on property 'portName' which implements
> 'NSCopying' protocol not appropriate with -fobjc-gc-only"
>
> So, is it really inappropriate? It seems very appropriate to assign
> the pointer rather than allocate a new object and copy it,
> especially for immutable objects.
No, it's not.
The issue is that a object-pointer property might *either* be an
attribute (i.e. a value which should be copied) *or* a relationship
(i.e. a connection to another object which should not be copied), and
there's no syntactic difference.
For some inexplicable** reason, Apple has chosen to try to tell the
difference based on whether the object implements NSCopying, which
really has nothing to do with it.
The solution is, of course to specify "copy" or "assign" on every such
property. That's a good idea anyway, since it documents the kind of
property, and makes you stop to think about which is the correct
behavior for the property.
--
** Actually, I think it's not totally inexplicable. NSString* and
NSNumber* are possibly the most common property types, and they're
almost always attributes, rarely relationships, so it's almost always
a bad idea to use "assign" for them. My guess is that this warning
exists primarily to remind you to specify "copy" for strings and
numbers.
Incidentally, I bug-reported this warning and was mostly rebuffed,
except that in gcc 4.2 the warning now reads:
> "warning: default 'assign' attribute on property 'portName' which
> implements 'NSCopying' protocol not appropriate with -fobjc-gc-only"
which is infinitesimally more accurate. I'm very proud of that
"default" -- it proves that even we little people can change the
world. :) -
On Sun, Sep 21, 2008 at 5:04 PM, Rick Mann <rmann...> wrote:
> According to the Obj-C 2.0 docs:
>
>> assign
>> Specifies that the setter uses simple assignment. This is the default.
>>
>> If your application uses garbage collection, if you want to use assign for
>> a property whose class adopts the NSCopying protocol you should specify the
>> attribute explicitly rather than simply relying on the default—otherwise you
>> will get a compiler warning. (This is to reassure the compiler that you
>> really do want to assign the value, even though it's copyable.)
>>
>
> But the warning is:
>
> "warning: 'assign' attribute on property 'portName' which implements
> 'NSCopying' protocol not appropriate with -fobjc-gc-only"
>
> So, is it really inappropriate? It seems very appropriate to assign the
> pointer rather than allocate a new object and copy it, especially for
> immutable objects.
I'd guess that it's considered inappropriate because "assign" has the
implication that the property is a weak reference, but it will be a
strong reference under GC*. Use "retain", as it implies the correct
strong reference semantics, but when running under GC will generate a
straight-assignment setter.
* A property can be made weak by declaring its backing ivar as __weak,
but this is somewhat unusual, and in any case is not affected by the
property declaration.
Mike -
On Sep 21, 2008, at 15:00, Quincey Morris wrote:
>> So, is it really inappropriate? It seems very appropriate to assign
>> the pointer rather than allocate a new object and copy it,
>> especially for immutable objects.
>
> No, it's not.
Sorry, just to clarify -- no, it's not really inappropriate. Yes, it's
very appropriate to assign the pointer sometimes. -
On Sep 21, 2008, at 15:22:22, Quincey Morris wrote:
> On Sep 21, 2008, at 15:00, Quincey Morris wrote:
>
>>> So, is it really inappropriate? It seems very appropriate to
>>> assign the pointer rather than allocate a new object and copy it,
>>> especially for immutable objects.
>>
>> No, it's not.
>
> Sorry, just to clarify -- no, it's not really inappropriate. Yes,
> it's very appropriate to assign the pointer sometimes.
I was going to say...especially for immutable objects like NSString
and NSNumber, which you pointed out are almost always used as
attributes and not as relationships, it seems to make more sense (from
a performance standpoint, at least) to just assign the pointer and not
allocate a new object and copy the contents.
On Sep 21, 2008, at 15:02:08, Michael Ash wrote:
> Use "retain", as it implies the correct
> strong reference semantics, but when running under GC will generate a
> straight-assignment setter.
If that's the case, then I think it makes sense to specify "retain" in
all those instances. I didn't like "retain" because, well, it implied
that a retain count was going up, despite the fact that I'm in a GC-
only app.
Thanks!
--
Rick -
On Sep 21, 2008, at 18:08, Rick Mann wrote:
> I was going to say...especially for immutable objects like NSString
> and NSNumber, which you pointed out are almost always used as
> attributes and not as relationships, it seems to make more sense
> (from a performance standpoint, at least) to just assign the pointer
> and not allocate a new object and copy the contents.
You can expect that copying of immutable objects like NSString and
NSNumber may not actually copy but return a reference to the original.
So you're better off declaring them "copy". Also keep in mind that
even if the property is declared as NSString*, a client may actually
pass a mutable string to the setter as the new value, and in that case
you really do want a copy.
Again, I'd recommend using "copy" or "assign" as a semantic descriptor
on the property, and not worry about the copying performance of the
implementation unless you discover a good measurable reason to do so.


