• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: readonly property which is a mutable array
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: readonly property which is a mutable array


  • Subject: Re: readonly property which is a mutable array
  • From: Keary Suska <email@hidden>
  • Date: Fri, 19 Nov 2010 11:00:34 -0700

On Nov 18, 2010, at 7:51 PM, Ken Thomases wrote:

> On Nov 18, 2010, at 9:33 AM, Keary Suska wrote:
>
>> On Nov 18, 2010, at 5:35 AM, Remco Poelstra wrote:
>>
>>> Hi,
>>>
>>> I've a object like to following:
>>> @interface <Proto> {
>>> 	NSMutableArray *items;
>>> }
>>> @property (nonatomic,readonly) NSMutableArray *items;
>>> @end
>>>
>>> I also have a protocol as follows:
>>> @protocol Proto
>>> @property (nonatomic,readonly) NSArray *items;
>>> @end
>>>
>>> I of course want the items to be read only for the outside world, but the object itself should be able to modify it. Now the compiler complains about the properties not matching. How should I solve this? Make a custom getter that returns an immutable array? Make the property refer to a mutable array? Make the property an immutable array and make copies of the array while modifying it?
>>
>> The ivar type and the property type don't have to match. In fact, there does not need to be any ivar backing whatsoever to properties.
>>
>> Change your property declaration to NSArray *, and implement the getter with [[array copy] autorelease] or similar.
>
> You don't need to implement the getter.  The Cocoa docs are very clear that callers must respect the declared type of properties (i.e. return type of getters).  That is, if the getter is declared to return an immutable NSArray, then callers must not interrogate the returned object to determine if it's really mutable nor invoke mutation methods on it.  It may be, and often is (even in framework classes), that such a method returns an object that is, in fact, an NSMutableArray.  That's an irrelevant implementation detail.

We could say that it *should* be an implementation detail, but may lead to bugs if a copy isn't returned, as even Cocoa does *not* guarantee that an object will not be mutated out from underneath you (I include by reference the responses in this thread made by Jonathan and Andreas).

Case in point, get the array of table columns from an NSTableView, then while enumerating them remove a column from the tableview and BAM!

So, I think we should write code to guarantee immutability to the caller, regardless of type of course, which is the API contract you spell out. I see the easiest way as always returning a copy in the getter. But I don't remember how synthesized accessors are implemented on the back-end, so I don't know if they do the smart thing by default...

Keary Suska
Esoteritech, Inc.
"Demystifying technology for your home or business"

_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

  • Follow-Ups:
    • Re: readonly property which is a mutable array
      • From: David Duncan <email@hidden>
References: 
 >readonly property which is a mutable array (From: Remco Poelstra <email@hidden>)
 >Re: readonly property which is a mutable array (From: Keary Suska <email@hidden>)
 >Re: readonly property which is a mutable array (From: Ken Thomases <email@hidden>)

  • Prev by Date: Re: Subclasses, protocols and properties - compiler warning
  • Next by Date: Re: readonly property which is a mutable array
  • Previous by thread: Re: readonly property which is a mutable array
  • Next by thread: Re: readonly property which is a mutable array
  • Index(es):
    • Date
    • Thread