Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 311 Vote(s) - 3.47 Average
  • 1
  • 2
  • 3
  • 4
  • 5
ARC and bridged cast

#1
With ARC, I can no longer cast `CGColorRef` to `id`. I learned that I need to do a bridged cast. According [clang docs][1]:

> A **bridged cast** is a C-style cast annotated with one of three keywords:
>
> `(__bridge T) op` casts the operand to the destination type `T`. If `T`
> is a retainable object pointer type, then `op` must have a
> non-retainable pointer type. If `T` is a non-retainable pointer type,
> then op must have a retainable object pointer type. Otherwise the cast
> is ill-formed. There is no transfer of ownership, and ARC inserts no
> retain operations.
>
> `(__bridge_retained T) op` casts the operand, which must have
> retainable object pointer type, to the destination type, which must be
> a non-retainable pointer type. ARC retains the value, subject to the
> usual optimizations on local values, and the recipient is responsible
> for balancing that +1.
>
> `(__bridge_transfer T) op` casts the operand, which must have
> non-retainable pointer type, to the destination type, which must be a
> retainable object pointer type. ARC will release the value at the end
> of the enclosing full-expression, subject to the usual optimizations
> on local values.
>
> These casts are required in order to transfer objects in and out of
> ARC control; see the rationale in the section on conversion of
> retainable object pointers.
>
> Using a `__bridge_retained` or `__bridge_transfer` cast purely to convince
> ARC to emit an unbalanced retain or release, respectively, is poor
> form.

In what kind of situations would I use each?

For example, `CAGradientLayer` has a `colors` property which accepts an array of `CGColorRef`s. My guess is that I should use `__brige` here, but exactly why I should (or should not) is unclear.

[1]:

[To see links please register here]

Reply

#2
As a follow-on, in this specific case, if you are on iOS, Apple recommends using UIColor and its `-CGColor` method to return the CGColorRef into the `colors` NSArray. In the [Transitioning to ARC Release Notes][1], under the section "The Compiler Handles CF Objects Returned From Cocoa Methods", it is indicated that using a method like `-CGColor` which returns a Core Foundation object will automatically be handled properly by the compiler.

Thus, they suggest using code like the following:

CAGradientLayer *gradientLayer = (CAGradientLayer *)[self layer];
gradientLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor darkGrayColor] CGColor],
(id)[[UIColor lightGrayColor] CGColor], nil];

Note that as of right now, Apple's example code is missing the (id) cast I have above, which is still necessary to avoid a compiler error.

[1]:

[To see links please register here]

Reply

#3
I agree that the description is confusing. Since I just grasped them, I'll try to summarize:

- `(__bridge_transfer <NSType>) op` or alternatively `CFBridgingRelease(op)` is used to consume a retain-count of a `CFTypeRef` while transferring it over to ARC. This could also be represented by `id someObj = (__bridge <NSType>) op; CFRelease(op);`

- `(__bridge_retained <CFType>) op` or alternatively `CFBridgingRetain(op)` is used to hand an `NSObject` over to CF-land while giving it a +1 retain count. You should handle a `CFTypeRef` you create this way the same as you would handle a result of `CFStringCreateCopy()`. This could also be represented by `CFRetain((__bridge CFType)op); CFTypeRef someTypeRef = (__bridge CFType)op;`

- `__bridge` just casts between pointer-land and Objective-C object-land. If you have no inclination to use the conversions above, use this one.

Maybe this is helpful. Myself, I prefer the `CFBridging…` macros quite a bit over the plain casts.
Reply

#4
I found another explanation in the iOS documentation that I think is easier to understand:

* `__bridge` transfers a pointer between Objective-C and Core Foundation with no transfer of ownership.

* `__bridge_retained (CFBridgingRetain)` casts an **Objective-C** pointer to a **Core Foundation** pointer and also transfers ownership to you.

**You are responsible** for calling CFRelease or a related function to relinquish ownership of the object.

* `__bridge_transfer (CFBridgingRelease)` moves a **non-Objective-C** pointer **to Objective-C** and also transfers ownership to ARC.

**ARC is responsible** for relinquishing ownership of the object.

Source: [Toll-Free Bridged Types][1]


[1]:

[To see links please register here]

"Toll-Free Bridged Types"
Reply



Forum Jump:


Users browsing this thread:
2 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through