Search code examples
objective-cautomatic-ref-countingcore-foundation

How to transfer Core Foundation ownership with a mix of Create/Get?


Is it correct to use CFBridgingRelease in the following code?

CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
PopulateArray(&items);    
CFDictionaryRef dict = CFArrayGetValueAtIndex(items, 0);
CFData data = CFDictionaryGetValue(dict, "key");

NSMutableArray* datas = [[NSMutableArray alloc] initWithObjects:CFBridgingRelease(data), nil];
return datas;

According to the Get Rule I'm just getting data so I don't own it, and shouldn't be transferring ownership. But my reasoning is that ultimately data is being created here inside the items structure, and I'm returning it in an array so I want it to be reference-counted afterwards so I should transfer ownership.


Solution

  • According to the Get Rule I'm just getting data so I don't own it, and shouldn't be transferring ownership.

    Correct, to transfer ownership you must have ownership, and you don't. Transferring ownership when you don't have it is dangerous, expect crashes.

    But my reasoning is that ultimately data is being created here inside the items structure, and I'm returning it in an array so I want it to be reference-counted afterwards so I should transfer ownership.

    No, what you do is just transfer the reference without ownership:

    (__bridge NSData *)data
    

    And now ARC will track the result of that expression. When you place the resulting reference in your NSMutableArray the array will take ownership. At this point your data has at least two owners, items and datas. ARC manages the lifetime of datas and any objects it refers to, however you must release items yourself when it is no longer needed. You can release it immediately after you've placed your data in datas if you do not otherwise need it.

    HTH