Core Foundation Framework
The Core Foundation Framework (corefoundation.framework) is a set of C-language interfaces that provide basic data management and service capabilities for iOS applications. The following lists the data that the framework supports for management and what services are available:
Group data types (arrays, collections, etc.)
Package
String Management
Date and time management
RAW Data Block Management
Preference Management
URL and Data flow operations
Threading and Runloop
Port and Soket Communication
The Core Foundation framework is closely related to the foundation framework, which provides interfaces for the same functionality, but the foundation framework provides the OBJECTIVE-C interface. If you use the foundation object with the core foundation type, you can take advantage of the "toll-free bridging" between the two frameworks. The so-called toll-free bridging is that you can use some of the types in the core Foundatio and foundation frameworks at the same time in a framework's methods or functions. Many data types support this feature, including group and string data types. The class and type descriptions for each frame are toll-free bridged for an object and what object bridging should be described.
For further information, please read the core Foundation Framework reference.
Since Xcode4.2 began to import the arc mechanism, Apple has added many keywords for transformation in order to support the transformation between objects. This tells us to understand its usage and the reasons for its creation.
Introduction
Let's take a look at the arc is invalid, we write the ID type to void* type:
ID obj = [[NSObject alloc] init];
void *p = obj;
Conversely, when the Void* object is changed back to the ID type, simply write as follows,
id obj = p;
[obj release];
But when the above code is valid for arc, it has the following error:
Error:implicit conversion of an objective-c pointer
To ' void * ' are disallowed with ARC
void *p = obj;
^
Error:implicit conversion of a non-objective-c pointer
Type ' void * ' to ' ID ' are disallowed with ARC
id o = p;
^
__bridge
To solve this problem, we use the __bridge keyword to convert the ID type to the void* type. Look at the following example.
ID obj = [[NSObject alloc] init];
void *p = (__bridge void *) obj;
ID o = (__bridge id) p;
Converting an object type of objective-c to a void* type with __bridge is the same as a variable that is decorated with the __unsafe_unretained keyword. The owner of the object that is being replaced needs to explicitly manage the object life cycle, without the problem of unusual access.
In addition to __bridge, there are two __bridge-related type conversion keywords:
__bridge_transfer
__bridge_retained
Next, we'll look at the differences between the two keywords.
__bridge_retained
First look at the example program using the __bridge_retained keyword:
ID obj = [[NSObject alloc] init];
void *p = (__bridge_retained void *) obj;
From the name we should be able to understand its meaning: when a type is converted, the ownership of its object is also held by the transformed variable. If it is not the arc code, it resembles 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 range of curly braces is out, p still points to a valid entity. Indicates that he owns the object and that the object has not been destroyed because of its defined scope.
__bridge_transfer
Conversely, when you want to have a variable that has ownership of the object, you need to use the __bridge_transfer keyword after the type conversion to release the original ownership. Text a bit around the mouth, we still see a piece of code it.
If arc is invalid, we may need to write the following code.
The p variable originally held ownership of the object
ID obj = (id) p;
[obj retain];
[(ID) p release];
Then, after arc is valid, we can replace it with the following code:
The p variable originally held ownership of the object
ID obj = (__bridge_transfer id) p;
As can be seen, __bridge_retained is the compiler for us to do the retain operation, and __bridge_transfer is for us to do the release1.
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 primarily objects of the core foundation Framework with the C language implementation, as well as the concept of object reference counting, but not the Cocoa framework::foundation Framework ret Ain/release, but its own cfretain/cfrelease interface.
These two objects can be converted and manipulated to each other, do not use arc, the simple type of C reason conversion, do not need to consume CPU resources, so called toll-free bridged. For example, Nsarray and Cfarrayref, NSString and Cfstringref, although they belong to different frameworks, but have the same object structure, they can be converted with the standard C type.
For example, when you 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 also simple to convert with the standard C type.
However, in the event that arc is valid, a compile error similar to the following will appear:
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 has prompted what we need to do: to transform with __bridge or __bridge_retained, the difference is to change the ownership of the object.
Because the objective-c is an arc-managed object, and the core Foundation is not an arc-managed object, it is only intentional to convert it, which is a concept with the ID type to void* conversion. That is, when the two types (with ARC management, no arc management) are converted, you need to tell the compiler how to handle the ownership of the object.
In the example above, the code after using __bridge/__bridge_retained is as follows:
NSString *string = [NSString stringWithFormat: ...];
Cfstringref cfstring = (__bridge cfstringref) string;
Simply performs a type conversion, without transferring ownership, that is, cfstring cannot be used when the string object is freed.
NSString *string = [NSString stringWithFormat: ...];
Cfstringref cfstring = (__bridge_retained cfstringref) string;
...
Cfrelease (cfstring); Because core foundation objects are not part of the ARC Management category, you need to release
Use __bridge_retained to transfer ownership by converting the retain processing at the target (cfstring). Cfstring can use a specific object even if the string variable is freed. Just one thing, because core Foundation objects are not part of the ARC Management category, you need to release them yourself.
In fact, within the core Foundation, the following functions are provided to enable mutual conversion of the core Foundation object type to the Objective-c object type.
Cftyperef Cfbridgingretain (id X) {
Return (__bridge_retained cftyperef) X;
}
ID cfbridgingrelease (cftyperef X) {
return (__bridge_transfer ID) X;
}
Therefore, you can replace the __bridge_retained keyword with cfbridgingretain:
NSString *string = [NSString stringWithFormat: ...];
Cfstringref cfstring = Cfbridgingretain (string);
...
Cfrelease (cfstring); Because Core Foundation is not within the ARC management scope, active release is required.
__bridge_transfer
While ownership is being shifted, the converted variable loses ownership of the object. The __bridge_transfer keyword is often used when the core foundation object type is converted to the Objective-c object type.
Cfstringref cfstring = cfstringcreate ... ();
NSString *string = (__bridge_transfer NSString *) cfstring;
Cfrelease (cfstring); Since the ownership of the object has been transferred with __bridge_transfer, it is not necessary to call release
Again, we can use Cfbridgingrelease () instead of the __bridge_transfer keyword.
Cfstringref cfstring = cfstringcreate ... ();
NSString *string = cfbridgingrelease (cfstring);
Summarize
From the above study we understand the use of type conversion in ARC, then we actually use in accordance with what principle or method to distinguish between using, below I summed up a few key elements.
Determine if the type being converted is an ARC-managed object
Core Foundation object types are not in the ARC management category
Cocoa Framework::foundation Object Type (that is, commonly used objectie-c object type) within the scope of ARC management
If you are not in the ARC management category, be aware of who is responsible for the release.
What are the life cycles of various objects?
1. Declaration of the ID obj, in fact, is the default declaration of a __strong modified variable, so the compiler automatically added retain processing, so that the __bridge_transfer keyword only for us to do the release processing.
Use and difference of __bridge,__bridge_transfer and __bridge_retained "reprint"