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.
previous month september 2008 next month
MTWTFSS
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30          
Go to today