Toll-Free Bridging

Understand what toll-free bridging is, which Foundation and Core Foundation types can interoperate through it, and how ARC's three bridge casts -- __bridge, __bridge_retained, and __bridge_transfer -- each move an object across the Objective-C/Core Foundation boundary with a different ownership outcome, so that bridged code neither leaks memory nor crashes from a use-after-free or a double release.

Core Foundation predates both Objective-C's object model as commonly used today and ARC entirely -- it is a C-based framework, with its own manual retain/release discipline (CFRetain and CFRelease), that Foundation classes like NSString, NSArray, and NSDictionary were deliberately designed to share memory layout with. Toll-free bridging is the name for that relationship: certain Core Foundation types and their Foundation counterparts are, at the binary level, the exact same object, which means a pointer to one can be treated as a pointer to the other with zero copying and zero conversion cost -- 'toll-free.' The catch is that Core Foundation and ARC each have their own idea of who owns an object and are not aware of each other's bookkeeping, so crossing that boundary requires telling the compiler explicitly what should happen to ownership at the moment of the cast. That is exactly what __bridge, __bridge_retained, and __bridge_transfer are for, and getting them wrong is one of the most common sources of crashes in Objective-C code that touches Core Foundation, Core Graphics, or Core Text APIs. This lesson builds directly on the Core Foundation lesson's introduction to CFTypeRef-style objects and on the ARC and Manual Reference Counting lessons' treatment of ownership, and it assumes familiarity with all three.

What Toll-Free Bridging Actually Means

Toll-free bridging is a binary-compatibility guarantee, not a language feature that converts one type into another at runtime. When Apple's frameworks describe CFStringRef and NSString as toll-free bridged, they mean that the two types describe the identical underlying object in memory -- there is no hidden allocation, no byte copying, and no translation step when a value crosses between them. The word 'toll-free' contrasts this directly with the alternative: converting between two genuinely different representations, which would cost CPU time and memory (a 'toll'). Casting a CFStringRef to an NSString * is closer to relabeling a variable's type than to calling a conversion function.

This is only possible because Apple engineered specific Core Foundation types to share their internal object layout with a specific Foundation class from the very beginning. It is not a general property of Core Foundation -- most CF types have no Foundation counterpart at all, and the reverse is true too. Toll-free bridging exists for a specific, documented list of pairs, and only those pairs can be cast between the two worlds this way.

Because the object itself does not change, only its declared type changes, everything about the object that is independent of language -- its actual data, its identity, its address in memory -- stays exactly the same on both sides of a bridge cast. What does change, and what this entire lesson is about, is which memory-management system believes it is responsible for that object's lifetime at any given moment.

• Toll-free bridging means a CF type and an NS type share identical binary layout -- casting between them costs nothing at runtime. • It applies only to a specific, documented set of type pairs, not to Core Foundation and Foundation types in general. • The object itself never changes across a bridge cast -- only which type the compiler treats it as, and which memory-management system is considered responsible for it.

Which Foundation and Core Foundation Types Interoperate

The most commonly used toll-free bridged pairs mirror Foundation's core value types almost one-to-one: CFStringRef with NSString, CFMutableStringRef with NSMutableString, CFArrayRef with NSArray, CFMutableArrayRef with NSMutableArray, CFDictionaryRef with NSDictionary, CFMutableDictionaryRef with NSMutableDictionary, CFDataRef with NSData, CFDateRef with NSDate, CFNumberRef with NSNumber, CFURLRef with NSURL, CFSetRef with NSSet, and CFAttributedStringRef with NSAttributedString. Each of these pairs behaves identically for the purposes of bridging: whichever side you start from, a bridge cast produces a pointer of the other side's type referring to the exact same underlying object.

It is worth being precise about what is not toll-free bridged, because it is a common source of confusion covered in the Core Foundation lesson: many Core Foundation types -- CGColorRef, CGImageRef, CTFontRef among them -- have no Foundation counterpart at all and cannot be bridged with __bridge, __bridge_retained, or __bridge_transfer, because there is no NS-side type sharing their layout. Attempting a bridge cast on a non-bridged CF type is simply a compile error; the compiler already knows the documented list of pairs and will reject anything outside it.

The practical situations where toll-free bridging shows up are almost always at the seam between a pure-Objective-C codebase and a lower-level API that predates ARC and Foundation-style APIs -- Core Text layout code that hands back CFAttributedStringRef, Core Graphics code that consumes a CFStringRef font name, or any C function whose header was written against Core Foundation types before an Objective-C wrapper existed for the same functionality.

• Commonly bridged pairs: CFStringRef/NSString, CFArrayRef/NSArray, CFDictionaryRef/NSDictionary, CFDataRef/NSData, CFDateRef/NSDate, CFNumberRef/NSNumber, CFURLRef/NSURL, CFSetRef/NSSet, CFAttributedStringRef/NSAttributedString. • Mutable CF types bridge to their mutable NS counterparts the same way: CFMutableArrayRef with NSMutableArray, and so on. • Not every CF type has an NS counterpart -- CGColorRef, CGImageRef, and CTFontRef, for example, cannot be bridged at all; the compiler enforces the documented pair list. • Toll-free bridging matters most at the boundary between ARC-managed Objective-C code and older or lower-level C APIs like Core Text and Core Graphics.

ARC's View of the Boundary: Why a Plain Cast Is Not Enough

Under ARC, the compiler tracks every strong reference to every Objective-C object and inserts retain and release calls automatically, exactly as the ARC lesson describes. Core Foundation has never worked that way: CFRetain and CFRelease are ordinary C functions that a programmer calls by hand, and ARC has no visibility into them at all -- it does not know when a CFRetain happens, and it will never automatically call CFRelease on your behalf, because CFTypeRef values are, as far as ARC's own bookkeeping is concerned, not Objective-C objects.

This is precisely the gap that makes a plain C-style cast insufficient and dangerous when crossing between an NSString * and a CFStringRef: an ordinary cast changes the compiler's belief about a pointer's type, exactly as the Advanced Objective-C Type System lesson describes for any cast, but it says nothing at all about who is now responsible for keeping the object alive. ARC therefore requires one of three explicit bridge-cast keywords -- __bridge, __bridge_retained, or __bridge_transfer -- any time code casts between an Objective-C object pointer and a Core Foundation pointer type. Leaving the keyword off is a compile error, precisely because the compiler refuses to guess which of the three very different ownership outcomes you intend.

Each of the three keywords answers the exact same question -- 'after this cast, who owns the object?' -- with a different answer, and choosing the wrong one for a given situation is what produces the two classic failure modes this lesson covers: a use-after-free, when nobody actually retains an object that needed to be kept alive, and a double release (or over-release crash), when both ARC and manual CFRelease calls each believe they are responsible for releasing the same object.

• ARC tracks and automatically manages Objective-C object lifetimes; Core Foundation's CFRetain/CFRelease are separate, manual, and invisible to ARC. • A bridge cast is mandatory, not optional, any time a pointer crosses between an NS type and a CF type under ARC. • The three bridge keywords each answer the same question -- who owns the object after this cast -- with a different answer. • Choosing the wrong keyword is the direct cause of the use-after-free and double-release bugs this lesson demonstrates.

__bridge: Casting Without Any Ownership Transfer

__bridge performs the simplest possible bridge cast: it changes the pointer's type from one side of a toll-free bridged pair to the other, and does absolutely nothing to ownership. Whoever already owned the object before the cast still owns it afterward, and the cast itself neither retains nor releases anything. This is the correct choice precisely when the object's lifetime is already guaranteed by something else for at least as long as the bridged pointer will be used -- most commonly, when an NSString * that ARC already keeps alive via a __strong local variable is temporarily viewed as a CFStringRef to pass into a Core Foundation function that only reads it during the call.

The spec example -- casting an NSString you already hold as objcString into a CFStringRef, and casting a CFStringRef you already have into an NSString * -- is the textbook __bridge situation in both directions: nothing new is being created or destroyed, ownership is not moving anywhere, and the underlying object's actual retain count is completely unaffected by the cast itself.

The danger with __bridge is entirely about timing, not about the cast's own correctness: because __bridge transfers no ownership, the bridged pointer is only valid for as long as whatever already owns the object keeps it alive. If the original strong reference goes away -- the __strong local variable it came from is reassigned, or the autoreleased CF object is not otherwise retained -- while a __bridge-cast CFStringRef is still being used, that CFStringRef becomes a dangling reference to deallocated memory.

• __bridge: pure type relabeling -- no retain, no release, no ownership transfer of any kind. • Correct when the object's existing owner (an ARC __strong variable, typically) already guarantees the object outlives the bridged pointer's use. • The classic direction for both of the spec's example casts: viewing an already-owned NSString as a CFStringRef, or an already-owned CFStringRef as an NSString. • Dangerous only when the original owner releases the object while the __bridge-cast pointer is still in use -- see the use-after-free mistake below.

__bridge_retained (CFBridgingRetain): Transferring Ownership to Core Foundation

__bridge_retained casts an Objective-C object pointer to a Core Foundation pointer type and, unlike __bridge, also performs a retain on the object as part of the cast -- ARC hands ownership over to the Core Foundation side of the boundary, and it is now the caller's responsibility to eventually call CFRelease on that value, exactly as if it had been created directly by a Core Foundation 'Create' function. The Foundation function CFBridgingRetain(obj) does the identical thing as a plain function call and is often preferred for readability, especially outside of a plain cast expression.

This is the correct cast whenever a bridged value needs to outlive the scope of the ARC variable it came from -- most often when handing an object into a C API that stores the pointer for later use (a callback context, a struct field, a C data structure) rather than merely reading it during the current call. Without __bridge_retained in that situation, ARC would be free to release the object as soon as its own strong reference goes out of scope, even though the C code on the other side still expects to use it later.

Because __bridge_retained genuinely increments the retain count, every __bridge_retained (or CFBridgingRetain) call must be matched, exactly once, by a corresponding CFRelease when the Core Foundation side is done with the object -- otherwise the object leaks, kept alive forever by a retain that nothing ever balances.

• __bridge_retained (equivalently, CFBridgingRetain(obj)): casts NS -> CF and retains the object -- ownership genuinely transfers to the Core Foundation side. • Correct when a C API will hold onto the pointer beyond the current call, rather than just reading it and returning. • The caller now owns a +1 reference and must call CFRelease exactly once to balance it, or the object leaks. • Never use __bridge in a situation that actually needs __bridge_retained -- that mismatch is one of this lesson's featured mistakes.

__bridge_transfer (CFBridgingRelease): Transferring Ownership to ARC

__bridge_transfer is __bridge_retained's mirror image: it casts a Core Foundation pointer to an Objective-C object pointer and, critically, transfers an existing +1 ownership that the CF side was already holding over to ARC, without performing any additional retain of its own. After a __bridge_transfer cast, ARC treats the resulting Objective-C reference as if it had created it normally, and will release it automatically through its ordinary lifecycle -- you must not also call CFRelease on the original CF value, because that ownership has already moved.

CFBridgingRelease(cfValue) is the function form of exactly this cast and is the idiomatic way to write it in most code. The name is a deliberate hint about what is happening: the CF side is releasing its claim on the object -- handing its existing retain over to ARC -- rather than the function performing a release that discards the object outright.

The correct situation for __bridge_transfer is receiving a value from a Core Foundation function whose naming convention (following the Create Rule) indicates the caller already owns a +1 reference -- a function named CFStringCreateWithCString, CFArrayCreate, or anything containing Create or Copy in its name. Those functions hand back an object the caller is already responsible for releasing; __bridge_transfer is what lets ARC take over that existing responsibility instead of the code calling CFRelease by hand.

• __bridge_transfer (equivalently, CFBridgingRelease(cfValue)): casts CF -> NS and hands an existing +1 CF-side reference over to ARC. • No additional retain happens during the cast itself -- it transfers ownership that already existed, it does not create new ownership. • Correct specifically for values returned by Core Foundation Create/Copy-rule functions, which the caller already owns a reference to. • After __bridge_transfer, calling CFRelease on the original CF value yourself is wrong -- ARC now owns that reference, producing the double-release mistake covered below.

Lifetime Errors and Double-Release Risks

The two failure modes this lesson keeps returning to both come directly from mismatching a bridge cast against the ownership situation it is actually used in. A use-after-free happens when __bridge is used somewhere that needed __bridge_retained: the code assumes an existing owner keeps the object alive, but no such owner actually does, so the object is deallocated while the bridged CF pointer is still expected to be valid, and using it afterward reads or operates on already-freed memory -- one of the most dangerous classes of bug in any C-adjacent code because it may not crash immediately or consistently.

A double release happens when __bridge_transfer is used on a value ARC does not actually own a +1 reference to -- most commonly, calling __bridge_transfer (or CFBridgingRelease) on a CFStringRef obtained with __bridge in the first place, or on a Core Foundation 'Get' function's return value, which by convention hands back a reference the caller does not own and must not release. Because __bridge_transfer tells ARC 'you now own this reference and will release it eventually,' and the object never actually had that extra ownership to give away, the object's retain count is decremented one time too many -- the classic over-release, which corrupts the object and typically crashes the process, sometimes much later and far from the actual mistake.

The single rule that prevents both failure modes is to match the bridge keyword to the actual ownership convention of the API on the other side of the boundary: use __bridge only when something else already guarantees the object's lifetime for as long as you need it; use __bridge_retained only when you are deliberately handing new, balanced ownership to Core Foundation; and use __bridge_transfer only on a value you are certain the CF side already owns a +1 reference to and is handing off to you.

• Use-after-free: __bridge used where __bridge_retained was needed -- nothing actually kept the object alive, so it was already deallocated. • Double release: __bridge_transfer used on a value ARC does not truly own a +1 reference to -- the retain count is decremented once too often. • Both bugs trace back to the same root cause: mismatching the bridge keyword against the real ownership convention of the API being bridged to or from. • See the Core Foundation lesson for the Create/Copy/Get naming convention that tells you, up front, which ownership situation you are actually in.

The Three Bridge Casts

__bridge: no ownership change at all -- the existing owner (ARC or CF) keeps responsibility. __bridge_retained / CFBridgingRetain: ARC -> CF, and the cast itself performs a retain; CFRelease must balance it later. __bridge_transfer / CFBridgingRelease: CF -> ARC, and an existing CF-side +1 reference is handed to ARC; do not also call CFRelease.

CFStringRef cfString = (__bridge CFStringRef)objcString;
NSString *string = (__bridge NSString *)cfString;

CFStringRef retained = (__bridge_retained CFStringRef)objcString;
// equivalently: CFStringRef retained = CFBridgingRetain(objcString);

NSString *transferred = (__bridge_transfer NSString *)cfValue;
// equivalently: NSString *transferred = CFBridgingRelease(cfValue);

Code Examples

Both directions of the spec's example are __bridge because, in each case, something else already guarantees the object's lifetime for the duration it is used: objcString is a strong ARC parameter for the whole method body, and cfString is assumed to be valid for the whole describeCFString: call by whichever caller passed it in. Neither function performs a retain or a release -- they only relabel the pointer's type.

CFStringRef cfString = (__bridge CFStringRef)objcString;

userName only has a guaranteed lifetime for the duration of this method call; the C API, however, is expected to keep using the string after registerUserName: returns. __bridge_retained performs an actual retain as part of the cast, so the object survives independently of userName's own scope, at the cost of requiring exactly one matching CFRelease later, once the callback context that owns it is finished.

CFStringRef retainedName = (__bridge_retained CFStringRef)userName;

CFStringCreateMutableCopy's name marks it as a Create-rule function, so the caller already owns a +1 reference to upper before the bridge cast even happens. __bridge_transfer does not add a second retain -- it simply moves that already-existing ownership from Core Foundation's manual world into ARC's automatic one, so result is released normally, by ARC, whenever it is no longer needed.

NSString *result = (__bridge_transfer NSString *)upper;

CFBridgingRetain and CFBridgingRelease are ordinary Foundation functions that perform exactly the same operation as the __bridge_retained and __bridge_transfer cast keywords, respectively -- they exist purely for readability outside of a cast expression, and are fully interchangeable with the keyword forms shown in the earlier examples.

CFDictionaryRef snapshot = CFBridgingRetain(settings);

- (void)logWithCoreFoundation:(NSString *)objcString {
    // objcString is already kept alive by ARC as a __strong parameter --
    // __bridge just lets Core Foundation code read it during this call.
    CFStringRef cfString = (__bridge CFStringRef)objcString;
    CFIndex length = CFStringGetLength(cfString);
    NSLog(@"CF-measured length: %ld", (long)length);
    // No CFRelease here -- __bridge never took ownership, so there is
    // nothing to give back. objcString remains solely ARC's responsibility.
}

- (NSString *)describeCFString:(CFStringRef)cfString {
    // The reverse direction: cfString is already owned by whatever
    // Core Foundation code passed it in; __bridge just views it as NSString.
    NSString *string = (__bridge NSString *)cfString;
    return [NSString stringWithFormat:@"Value: %@", string];
}
void RegisterNameForCallback(CFStringRef name, void *context);

- (void)registerUserName:(NSString *)userName {
    // The C API stores 'name' and uses it later, after this method returns --
    // a plain __bridge would leave it dangling once userName's local
    // __strong reference is gone. __bridge_retained hands Core Foundation
    // its own, genuinely owned +1 reference instead.
    CFStringRef retainedName = (__bridge_retained CFStringRef)userName;
    RegisterNameForCallback(retainedName, NULL);
    // retainedName is now Core Foundation's responsibility -- it must be
    // released exactly once, later, wherever the callback context is torn down:
    //     CFRelease(retainedName);
}
- (NSString *)uppercasedCopy:(NSString *)input {
    // CFStringCreateMutableCopy follows the Create rule: the caller already
    // owns a +1 reference to whatever it returns.
    CFMutableStringRef upper =
        CFStringCreateMutableCopy(kCFAllocatorDefault, 0, (__bridge CFStringRef)input);
    CFStringUppercase(upper, NULL);

    // __bridge_transfer hands that existing +1 reference to ARC -- from this
    // point on, ARC will release 'result' automatically. Calling CFRelease
    // on 'upper' after this line would be a double release.
    NSString *result = (__bridge_transfer NSString *)upper;
    return result;
}
- (CFDictionaryRef)createSnapshotOfSettings:(NSDictionary *)settings {
    // CFBridgingRetain(...) is exactly equivalent to
    // (__bridge_retained CFDictionaryRef)settings -- some teams prefer the
    // function form because it reads clearly at a normal call site.
    CFDictionaryRef snapshot = CFBridgingRetain(settings);
    return snapshot;   // caller now owns +1 and must CFRelease it eventually
}

- (NSDictionary *)consumeSnapshot:(CFDictionaryRef)snapshot {
    // CFBridgingRelease(...) is exactly equivalent to
    // (__bridge_transfer NSDictionary *)snapshot.
    NSDictionary *settings = CFBridgingRelease(snapshot);
    return settings;   // ARC now owns and will release this normally
}

Ownership After Each Bridge Cast

__bridge changes nothing about ownership; __bridge_retained moves ownership from ARC to Core Foundation with a real retain; __bridge_transfer moves an existing Core Foundation reference to ARC without adding a new one.

__bridge
  ARC object  --(no change)-->  CF pointer
  Owner stays whoever already owned it.

__bridge_retained  (CFBridgingRetain)
  ARC object  --(+1 retain)-->  CF pointer
  Ownership moves to Core Foundation. Caller must CFRelease later.

__bridge_transfer  (CFBridgingRelease)
  CF pointer (+1 owned)  --(hand off, no extra retain)-->  ARC object
  Ownership moves to ARC. Do not also CFRelease the original CF value.

Where Toll-Free Bridging Shows Up in Real Codebases

In practice, toll-free bridging is almost never something application code reaches for casually -- it appears at specific, well-known seams: Core Text layout code that returns a CFAttributedStringRef or a CTLineRef built from one, Core Graphics font and color APIs that predate Objective-C wrappers for the same functionality, and low-level networking or security APIs (Security.framework, some CFNetwork entry points) that were written directly against Core Foundation. The discipline this lesson covers -- matching __bridge, __bridge_retained, and __bridge_transfer to each API's actual, documented ownership convention -- is exactly what the Core Foundation lesson's Create/Copy/Get naming rule exists to make predictable: read the function's name and documentation first, decide who owns the return value, and only then choose the matching bridge keyword, rather than guessing.

void RegisterNameForCallback(CFStringRef name, void *context); - (void)registerUserName:(NSString *)userName { CFStringRef name = (__bridge CFStringRef)userName; RegisterNameForCallback(name, NULL); // userName's __strong local can be released once this method returns -- // nothing else is keeping the object alive. } - (void)registerUserName:(NSString *)userName { CFStringRef name = (__bridge_retained CFStringRef)userName; RegisterNameForCallback(name, NULL); // Later, wherever the callback context is torn down: // CFRelease(name); }

__bridge transfers no ownership, so it relies entirely on something else keeping the object alive for as long as it is used. Here, nothing does: once registerUserName: returns, ARC is free to deallocate userName's object, leaving the C API's stored CFStringRef pointing at freed memory -- a use-after-free that the callback triggers later, often far from this code. __bridge_retained gives Core Foundation its own real, balanced ownership instead.

• (void)logLength:(NSString *)objcString { CFStringRef cfString = (__bridge CFStringRef)objcString; CFIndex length = CFStringGetLength(cfString); NSLog(@"length: %ld", (long)length); CFRelease(cfString); // WRONG: __bridge never retained anything } - (void)logLength:(NSString *)objcString { CFStringRef cfString = (__bridge CFStringRef)objcString; CFIndex length = CFStringGetLength(cfString); NSLog(@"length: %ld", (long)length); // No CFRelease here -- __bridge performed no retain, so there is // nothing for this code to balance. }

Because __bridge never incremented the retain count, calling CFRelease on its result decrements a count that this code never actually added to -- an over-release that can deallocate objcString's object while ARC still believes it owns a valid strong reference to it, corrupting memory and typically crashing later, once ARC's own release runs against an already-freed object.

• (NSString *)uppercasedCopy:(NSString *)input { CFMutableStringRef upper = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, (__bridge CFStringRef)input); CFStringUppercase(upper, NULL); NSString *result = (__bridge_transfer NSString *)upper; CFRelease(upper); // WRONG: ownership was already transferred to ARC return result; } - (NSString *)uppercasedCopy:(NSString *)input { CFMutableStringRef upper = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, (__bridge CFStringRef)input); CFStringUppercase(upper, NULL); NSString *result = (__bridge_transfer NSString *)upper; // No CFRelease here -- __bridge_transfer already handed the existing // +1 reference to ARC, which will release it in the ordinary way. return result; }

__bridge_transfer already moved the Create-rule function's existing +1 reference over to ARC as part of the cast -- result is now a perfectly ordinary, ARC-managed strong reference. Calling CFRelease on upper afterward decrements a reference ARC now believes is entirely its own to manage, producing a double release: the object's retain count drops one time too many, and the object is deallocated while ARC's own bookkeeping still expects it to be alive.

What does it actually mean for a Core Foundation type and a Foundation type to be 'toll-free bridged'? A. The compiler automatically writes a conversion function between the two types B. The two types share identical binary object layout, so a pointer to one can be treated as a pointer to the other at zero runtime cost C. Any Core Foundation type can be cast to any Foundation type with the __bridge keyword D. Toll-free bridging only works inside Core Text and Core Graphics code, nowhere else

B. The two types share identical binary object layout, so a pointer to one can be treated as a pointer to the other at zero runtime cost — Toll-free bridging is a binary-compatibility guarantee for a specific, documented set of type pairs (CFStringRef/NSString and similar). Because the underlying object is identical in memory, casting between the two costs nothing -- no copy, no conversion -- which is exactly what 'toll-free' refers to.

Why does ARC require an explicit __bridge, __bridge_retained, or __bridge_transfer keyword on every cast between an NS type and a CF type, rather than allowing a plain C-style cast? A. Because Core Foundation types are always larger in memory than Foundation types B. Because ARC automatically manages Objective-C object lifetimes but has no visibility into Core Foundation's separate, manual CFRetain/CFRelease bookkeeping, so it needs to be told explicitly what should happen to ownership at the cast C. Because the three keywords are purely stylistic and make no functional difference D. Because plain casts are not allowed anywhere in Objective-C, regardless of the types involved

B. Because ARC automatically manages Objective-C object lifetimes but has no visibility into Core Foundation's separate, manual CFRetain/CFRelease bookkeeping, so it needs to be told explicitly what should happen to ownership at the cast — ARC and Core Foundation each track ownership independently and are unaware of each other's bookkeeping. A bridge keyword is how the programmer tells the compiler explicitly what should happen to ownership at the exact moment a pointer crosses that boundary -- a plain cast alone would leave that question unanswered.

Which bridge cast is correct when handing an NSString to a C API that stores the pointer in a struct and uses it again after the current function returns? A. __bridge, because the string already exists and doesn't need any special handling B. __bridge_retained (or CFBridgingRetain), because the object needs its own, independently balanced ownership that outlives the current scope C. __bridge_transfer, because ownership should move entirely to the C side and never come back D. No bridge cast is needed if the C API only reads the string once

B. __bridge_retained (or CFBridgingRetain), because the object needs its own, independently balanced ownership that outlives the current scope — __bridge transfers no ownership, so it is only safe when something else already guarantees the object's lifetime for as long as it will be used. Since the C API here keeps the pointer beyond the current call, __bridge_retained performs the retain needed to keep the object alive independently, with the caller responsible for a matching CFRelease later.

A function follows Core Foundation's Create/Copy naming rule and returns a CFStringRef that the caller already owns a +1 reference to. What is the correct way to hand that value back to ARC as an NSString *? A. (__bridge NSString *)value, then call CFRelease on the original CF value separately B. (__bridge_retained NSString *)value, to add a second retain for safety C. (__bridge_transfer NSString *)value, or equivalently CFBridgingRelease(value), with no separate CFRelease call D. Any of the three bridge casts work identically here

C. (__bridge_transfer NSString *)value, or equivalently CFBridgingRelease(value), with no separate CFRelease call — The Create/Copy rule means the caller already owns a +1 reference before the bridge cast even happens. __bridge_transfer (or CFBridgingRelease) hands that existing reference to ARC without adding a new retain; calling CFRelease separately afterward would decrement a reference ARC now believes is entirely its own -- a double release.

What is the underlying cause of both the use-after-free and the double-release bugs this lesson describes? A. Using Core Foundation APIs at all, regardless of which bridge cast is chosen B. Choosing a bridge cast keyword that does not match the actual ownership convention of the API on the other side of the boundary C. Forgetting to import Core Foundation's header file D. Using CFBridgingRetain and CFBridgingRelease instead of the __bridge_retained and __bridge_transfer keywords

B. Choosing a bridge cast keyword that does not match the actual ownership convention of the API on the other side of the boundary — Both failure modes trace back to the same root cause: __bridge used where an object's lifetime actually needed a real retain (use-after-free), or __bridge_transfer used on a value ARC does not truly own a +1 reference to (double release). Matching the keyword to the API's real, documented ownership convention prevents both.

Write a method that takes an NSString *keyword parameter and calls a hypothetical C function CFIndex FindKeywordOccurrences(CFStringRef haystack, CFStringRef needle) that only reads both arguments during the call and does not store them. Then write a second method that receives a CFStringRef returned by a hypothetical Create-rule function CFStringRef CFCopyCanonicalPath(CFStringRef path) and returns it as an NSString *, taking care not to leak or double-release anything.

• (CFIndex)occurrencesOfKeyword:(NSString *)keyword inHaystack:(NSString *)haystack { return FindKeywordOccurrences((__bridge CFStringRef)haystack, (__bridge CFStringRef)keyword); // __bridge in both directions: the function only reads its arguments, // and both strings are already kept alive by their __strong parameters // for the whole duration of this call. } - (NSString *)canonicalPathFor:(NSString *)path { CFStringRef cfPath = (__bridge CFStringRef)path; CFStringRef canonical = CFCopyCanonicalPath(cfPath); // CFCopyCanonicalPath follows the Create/Copy rule: the caller already // owns a +1 reference to 'canonical'. __bridge_transfer hands that // reference to ARC without an extra retain, and no CFRelease is needed. return (__bridge_transfer NSString *)canonical; }

The first case is a __bridge situation in both directions -- nothing outlives the call, and nothing needs a retain. The second case is a __bridge_transfer situation -- CFCopyCanonicalPath's name follows the Create/Copy rule, so the caller already owns a +1 reference that needs to move to ARC, not be retained a second time.