IOS development: _ bridge ,__ bridge_transfer and _ bridge_retained

Source: Internet
Author: User

Core Foundation framework
The Core Foundation framework is a set of C language interfaces that provide basic data management and service functions for iOS applications. The following lists the data and services that the Framework supports for management:

Group data type (array, set, etc)
Package
String Management
Date and Time Management
Raw data block management
Preference Management
URL and data stream operations
Thread and RunLoop
Port and soket Communication
The Core Foundation framework is closely related to the Foundation framework. They provide interfaces for the same functions, but the Foundation framework provides Objective-C interfaces. If you mix the Foundation object with the Core Foundation type, you can use the "toll-free bridging" between the two frameworks ". The so-called Toll-free bridging means that you can use certain types of Core Foundatio and Foundation frameworks at the same time in methods or functions of a framework. Many data types support this feature, including group and string data types. The class and type descriptions of each framework determine whether an object is
Toll-free bridged, which specifies the object to be Bridge.

For more information, see the Core Foundation framework reference.


After Xcode4.2 began to import the ARC mechanism, Apple added many key words for transformation to support inter-object transformation. In this case, we will understand its usage and reasons.

Introduction
Let's take a look at the method for converting id type to void * type when the ARC is invalid:

Id obj = [[NSObject alloc] init];
Void * p = obj;
In turn, when the void * object is changed back to the ID type, it is simply written as below,

Id OBJ = P;
[OBJ release];
However, when the above Code is valid in the arc, the following error occurs:

   Error: implicit conversion of an objective-C pointer
       To 'void * 'is disallowed with arc
       Void * P = OBJ;
                 ^
 
   Error: implicit conversion of a non-objective-C pointer
       Type 'void * 'to 'id' is disallowed with arc
       Id o = P;
               ^

_ Bridge
To solve this problem, we use the _ bridge keyword to convert the id and void * types. Let's look at the example below.

Id obj = [[NSObject alloc] init];
 
Void * p = (_ bridge void *) obj;
 
Id o = (_ bridge id) p;
Convert the Objective-C object type to the void * type using _ bridge and modify the variable using the _ unsafe_unretained keyword. The owner of the object to be substituted must specify the object lifecycle management and avoid abnormal access.

Besides _ bridge, there are two type conversion keywords related to _ bridge:

_ Bridge_transfer
_ Bridge_retained
Next, let's take a look at the differences between the two keywords.

 

_ Bridge_retained
Let's look at the example program using the keyword _ bridge_retained:

Id obj = [[NSObject alloc] init];
 
Void * p = (_ bridge_retained void *) obj;
We should be able to understand its meaning in terms of name: when a type is converted, the ownership of its object will also be held by the variable after the transformation. If it is not the arc Code, it is similar to the following implementation:

Id OBJ = [[nsobject alloc] init];
 
Void * P = OBJ;
[(ID) P retain];
An actual example can be used to verify whether the object ownership is held.

Void * p = 0;
 
{
   Id OBJ = [[nsobject alloc] init];
   P = (_ bridge_retained void *) OBJ;
}
 
Nslog (@ "class = % @", [(_ bridge ID) P class]);
After the braces are defined, P still points to a valid entity. It indicates that he owns the object. The object is not destroyed because of its defined range.

_ Bridge_transfer
Instead, you need to use the _ bridge_transfer keyword to release the variable that originally owns the object after type conversion. The text is a bit confusing. Let's take a look at a piece of code.

If the arc is invalid, we may need to write the following code.

// The P variable originally holds the ownership of the object
Id OBJ = (ID) P;
[OBJ retain];
[(ID) P release];
After the arc is valid, we can replace it with the following code:

// The P variable originally holds the ownership of the object
Id OBJ = (_ bridge_transfer ID) P;
It can be seen that, __bridge_retained is the retain operation performed by the compiler for us, while _ bridge_transfer is release1 for us.

Toll-free bridged
In the IOS world, there are two main types of objects: Objective-C object and core Foundation object 0. Core Foundation objects are mainly objects of core foundation framework implemented in C language. They also have the concept of object reference count, but they are not cocoa framework: retain/release of foundation framework, instead, it is its own cfretain/cfrelease interface.

These two types of objects can be converted and operated on each other. When we do not use arc, we simply use C-type conversion and do not need to consume CPU resources. Therefore, they are called toll-free bridged. For example, nsarray, cfarrayref, nsstring, and cfstringref belong to different frameworks but have the same object structure. Therefore, standard C type conversion can be used.

For example, if we do not use arc, we use the following code:

Nsstring * string = [nsstring stringwithformat:...];
Cfstringref cfstring = (cfstringref) string;
Similarly, when the Core Foundation type is converted to the Objective-C type, it is simply possible to use the standard C type conversion.

However, when the ARC is valid, a compilation error similar to the following occurs:

   Cast of Objective-C pointer type 'nsstring * 'to C pointer type 'cfstringref' (aka 'const struct _ CFString * ') requires a bridged cast
   Use _ bridge to convert directly (no change in ownership)
   Use _ bridge_retained to make an ARC object available as a + 1 'cfstringref '(aka 'const struct _ CFString *')
The error shows how to perform the transformation with _ bridge or _ bridge_retained. The difference is that the ownership of the change object.

Because Objective-C is the object managed by the ARC, and Core Foundation is not the object managed by the ARC, We need to specifically convert it like this. This is a concept of converting the id type to void. That is to say, when the two types (with ARC Management, without ARC Management) are being converted, the compiler needs to tell how to handle the ownership of the object.

In the preceding example, the code after _ bridge/_ bridge_retained is as follows:

NSString * string = [NSString stringWithFormat:...];
CFStringRef cfString = (_ bridge CFStringRef) string;
Only type conversion is executed, and ownership is not transferred. That is to say, cfString cannot be used when the string object is released.

NSString * string = [NSString stringWithFormat:...];
CFStringRef cfString = (_ bridge_retained CFStringRef) string;
...
CFRelease (cfString); // because the Core Foundation object does not belong to the management scope of ARC, you need to release it yourself.
Use _ bridge_retained to transfer ownership by converting the retain at the target (cfString. Even if the string variable is released, cfString can still use a specific object. The only difference is that the Core Foundation object does not belong to the management scope of ARC, so you need to release it yourself.

In fact, the Core Foundation provides the following functions to convert the Core Foundation object type and the Objective-C object type.

CFTypeRefCFBridgingRetain (idX){
   Return(_ Bridge_retainedCFTypeRef) X;
}
 
IdCFBridgingRelease (CFTypeRefX){
   Return(_ Bridge_transferId) X;
}
Therefore, you can use CFBridgingRetain to replace the _ bridge_retained Keyword:

NSString * string = [NSString stringWithFormat:...];
CFStringRef cfString = CFBridgingRetain (string );
...
CFRelease (cfString); // because the Core Foundation is not within the scope of the ARC Management, you need to take the initiative to release.
_ Bridge_transfer
When ownership is transferred, the converted variable will lose the ownership of the object. When the Core Foundation object type is converted to the Objective-C object type, the _ bridge_transfer keyword is often used.

CFStringRef cfString = CFStringCreate ...();
Nsstring * string = (_ bridge_transfer nsstring *) cfstring;
 
// Cfrelease (cfstring); because the ownership of the object has been transferred with _ bridge_transfer, you do not need to call release
Similarly, we can use cfbridgingrelease () to replace the _ bridge_transfer keyword.

Cfstringref cfstring = cfstringcreate ...();
Nsstring * string = cfbridgingrelease (cfstring );


Summary
From the above learning, we learned how to use type conversion in Arc. What principles or methods should we use in actual use? Below I have summarized several key elements.

Determine whether the conversion type is an object managed by arc.
Core Foundation object types are not managed by arc
Cocoa framework: The Foundation object type (that is, the commonly used objectie-C object type) is under the management scope of arc.
If the objects are not in the scope of ARC Management, it is necessary to know who is responsible for release.
What is the lifecycle of various objects?
1. when ID obj is declared, A _ strong modified variable is declared by default, so the compiler automatically adds retain's processing, so the _ bridge_transfer keyword only performs release processing for us.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.