In cocoa application applications, we sometimes use core Foundation (CF), which is often converted between objective-C and CF. When the system uses arc, the compiler cannot automatically manage CF memory. At this time, you must use cfretain and cfrelease to manage CF memory.
For specific CF memory management rules, see memory.
Management programming guide for core Foundation
The conversion between OC and FC mainly involves the ownership of objects. There are two methods:
1. using macros, you can identify the owner from OC to CF or from CF to OC.
ns_inline cftyperef cfbridgingretain (id x) {
return (_ bridge_retain cftyperef) X;
}< br>
ns_inline ID cfbridgingrelease (cftyperef X) {
return (_ bridge_transfer ID) x;
}
2. Use Conversion characters, such as :__ bridge ,__ bridge_transfer ,__ bridge_retained
Id my_id;
Cfstringref my_cfref;
...
Nsstring * A = (_ bridge nsstring *) my_cfref; // Noop cast.
Cfstringref B = (_ bridge cfstringref) my_id; // Noop cast.
...
Nsstring * c = (_ bridge_transfer nsstring *) my_cfref; //-1 on the cfref
Cfstringref d = (_ bridge_retained cfstringref) my_id; // returned cfref is + 1
The following uses a detailed example to describe the memory management methods of OC and CF in the ARC. The cfurlcreatestringbyaddingpercentescapes () function is used as an example to describe the method used in the ARC and that used in the ARC.
In non-arc mode:
# Pragma mark-view Lifecycle
-(Void) viewdidload
{
[Super viewdidload];
Nslog (@ "= % @", [self escape: @ "wangjun"]);
}
-(Nsstring *) Escape :( nsstring *) Text
{
Return (nsstring *) cfurlcreatestringbyaddingpercentescapes (
Null,
(_ Bridge cfstringref) text,
Null,
Cfstr ("! * '();: @ & = + $ ,/? % # [] "), Cfstringconvertnsstringencodingtoencoding (nsutf8stringencoding ));;
}
No memory leakage is detected using instruments.
Next we will change the above project to the arc mode.
You can see that xcode automatically converts the above function:
# Pragma mark-view Lifecycle
-(Void) viewdidload
{
[Super viewdidload];
Nslog (@ "= % @", [self escape: @ "wangjun"]);
}
-(Nsstring *) Escape :( nsstring *) Text
{
Return ( _ Bridge_transfer Nsstring *) cfurlcreatestringbyaddingpercentescapes (
Null,
(_ Bridge cfstringref) text,
Null,
Cfstr ("! * '();: @ & = + $ ,/? % # [] "), Cfstringconvertnsstringencodingtoencoding (nsutf8stringencoding ));;
}
In arc, the conversion bridge between CF and OC is _ bridge. There are two ways:
- __ bridge_transfer arc takes over the management memory
- __ bridge_retained arc releases memory management
The above method is to convert from CF to OC nsstring object, use _ bridge_transfer, the object owner changes from CF to OC, and finally the arc takes over the memory management. Run the precedingCodeThere is no memory leakage when detecting with instruments.
The above code is equivalent:
-(nsstring *) Escape :( nsstring *) text
{< br> return cfbridgingrelease (cfurlcreatestringbyaddingpercentescapes (
null,
(_ bridge cfstringref) text,
null,
cfstr ("! * '();: @ & = + $ ,/? % # [] "), Cfstringconvertnsstringencodingtoencoding (nsutf8stringencoding);}
If you change the above Code:
-(Nsstring *) Escape :( nsstring *) Text
{
Return ( _ Bridge Nsstring *) cfurlcreatestringbyaddingpercentescapes (
Null,
(_ Bridge cfstringref) text,
Null,
Cfstr ("! * '();: @ & = + $ ,/? % # [] "), Cfstringconvertnsstringencodingtoencoding (nsutf8stringencoding ));;
}
Compilation will also succeed, but at this time with instruments detection, you can find the memory leakage:
Since CF has converted the OC, it has not released its own memory, nor has it handed over the memory management to the arc, So memory leakage occurs. Since _ bridge is only a reference to the same object, the ownership of the memory has not changed.
Next we will talk about the conversion from OC to CF. We need to release the memory management right of OC.
nsstring * S1 = [[nsstring alloc] initwithformat: @" Hello, % @! ", Name];
cfstringref S2 = (_ bridge_retained cfstringref) S1;
// do something with S2 //...
cfrelease (S2);
Finally, CF releases the memory.
The above code is equivalent:
Cfstringref S2 = cfbridgingretain (S1 );
//...
Cfrelease (S2 );
The following is a summary of the use of arc. Principles of conversion between OC and CF:
- when CF is converted to OC and the object owner changes, cfbridgingrelease () or _ bridge_transfer is used.
- when OC is converted to CF and the object owner changes, cfbridgingretain () or _ bridge_retained
- when one type is converted to another type, but the object owner is not changed, _ bridge is used.