Collection callbacks and toll free bridging

Christiaan Hofman cmhofman at gmail.com
Wed Apr 2 09:24:57 PDT 2008


On 2 Apr 2008, at 5:53 PM, Adam R. Maxwell wrote:

>
> On Wednesday, April 02, 2008, at 08:06AM, "Christiaan Hofman" <cmhofman at gmail.com 
> > wrote:
>>
>> On 2 Apr 2008, at 4:45 PM, Adam R. Maxwell wrote:
>>
>>>
>>> On Apr 2, 2008, at 7:25 AM, Christiaan Hofman wrote:
>>>> Hi all,
>>>>
>>>> I have some questions about how toll free bridging handles
>>>> callbacks for collections. I've searched the docs but came out
>>>> empty. Basically I have the following 2 questions:
>>>>
>>>> 1. Are Cocoa accessors doing anything besides some checking and
>>>> wrapping CF functions?
>>>> 2. What callbacks are used by collections initialized using Cocoa?
>>>>
>>>> Let me make this a bit more explicit for the example of
>>>> CFMutableDictionaryRef/NSMutableDictionary. NSMutableDictionary is
>>>> documented to copy the keys. So a more concrete version of my
>>>> question is: are the keys copied by the Cocoa methods, or by the CF
>>>> key callbacks?
>>>>
>>>> Context: I need a dictionary for keys that do not conform to
>>>> NSCopying. So can I use just use CFDictionaryCreateMutable to
>>>> create the dictionary and then use Cocoa methods for the rest?
>>>
>>> No, NSMutableDictionary is weird about this.  You must not use -
>>> setObject:forKey: because the copying is done in that method.  Mike
>>> Ash pointed this out to me on cocoa-dev a couple of years ago:
>>>
>>> http://www.cocoabuilder.com/archive/message/cocoa/2006/5/13/163439
>>>
>>> My bug report on this was duped to his, and the conclusion is that
>>> if you use setObject:forKey:, it will create a copy of your key,
>>> then invoke your custom callbacks /on the copy/:
>>>
>>> http://www.cocoabuilder.com/archive/message/cocoa/2006/7/10/167259
>>>
>>> Once you've used CFDictionaryAddValue, you can safely use
>>> objectForKey: and other Cocoa methods, though.  I still think the
>>> setObject:forKey: behavior is wrong, but at least I can avoid it.
>>>
>>> -- 
>>> adam
>>
>> Thanks Adam. Now my question was general, and this is just a specific
>> example.
>
> Ah, okay; sounded as if you were interested in NSMutableDictionary  
> in particular.

That was indeed the reason I asked it. But then I started wondering  
about the general situation.

>
>
>> Does anyone know the general story for any collection? Or is
>> the general story that I cannot trust toll free bridging for  
>> anything?
>
> Only Apple knows, and I think all you'll get out of them is weasel  
> words like the response  to Mike's bug:).  Within that reply,  
> though, it sounds as if custom callbacks are guaranteed to be  
> invoked and other behavior will be documented.  NSSet is documented  
> as retaining its keys instead of copying, so it works as expected.

Though the docs also say that Cocoa collections compare objects using  
isEqual:, even though custom callbacks for equality do seem to work.  
So that description is not completely correct (documentation bug?).

> Likewise NSArray.  OTOH, even with custom callbacks, I wouldn't try  
> passing e.g. an int to -[NSMutableArray addObject:]; it feels safer  
> to use CFArray functions for that.
>

That's right, in fact it *does* fail, because it checks for nil  
values . So it raises an exception when you add a zero int, while  
CFArrayAddValue has no problem adding a zero int.

> If you get a better response, please let me know!  I'm pretty  
> disillusioned with toll-free bridging since it's not quite as  
> transparent as the docs indicate.
>
> -- 
> adam

That's what I thought. In fact, even though Apple thinks the behavior  
is correct, I do think it's at least a documentation bug because of  
this, because the docs suggest toll free bridging is much less  
involved than it actually is. I'll file a bug report on this.

Christiaan



More information about the MacOSX-dev mailing list