Memory management in OC
Summary of memory management for converting Objective-C and Core Foundation objects to and from each other
1. ARC can help manage Objective-C objects for memory management issues, but it does not support Core Foundation objects, so there is a problem after conversion: who will release the used objects. This article focuses on memory management after type conversions.
Non-arc memory management
If ARC is not used, manual memory management will be clearer. After use, the converted object after release can be used.
/ / turn CFStringRef nsstrings
CFStringRef aCFString = (CFStringRef) [[NSString alloc] initWithFormat:@ "% @", string];
/ /...
CFRelease(aCFString);
/ / CFStringRef nsstrings
CFStringRef aCFString = CFStringCreateWithCString(kCFAllocatorDefault,
bytes,
NSUTF8StringEncoding);
NSString *aNSString = (NSString *)aCFString;
/ /...
[aNSString release];
Copy the code
ARC memory management
ARC made memory management a lot easier, but it only allowed us to manage Objective-C objects, not Core Foundation objects. Core Foundation objects must use CFRetain and CFRelease for memory management. So when you convert objective-C and Core Foundation objects to and from each other, you have to let the compiler know who’s responsible for releasing the object and whether or not ARC is handling it. Only proper handling can prevent memory leaks and double free crashes.
Depending on the requirements, there are three conversion modes
__bridge (without changing object ownership) __bridge_retained or CFBridgingRetain() (relieved of ARC ownership) __bridge_transfer or CFBridgingRelease() (given ARC ownership)
1. __bridge_retained or CFBridgingRetain ()
__bridge_retained or CFBridgingRetain() converts objective-C objects to Core Foundation objects, Bridges the ownership of the object to Core Foundation, and takes away the management of ARC. Later, the developer needs to manually release the object using CFRelease or related methods.
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *aNSString = [[NSString alloc]initWithFormat:@"test"];
CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString;
(void)aCFString;
// The correct approach is to execute CFRelease
//CFRelease(aCFString);
}
Copy the code
CFRelease not executed, causing a memory leak:
CFBridgingRetain() is the __bridge_retained macro method, and the following two lines are equivalent:
CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString;
CFStringRef aCFString = (CFStringRef) CFBridgingRetain(aNSString);
2. The __bridge_transfer or CFBridgingRelease ()
__bridge_Transfer or CFBridgingRelease() converts non-Objective-C objects to Objective-C objects while handing over object management to ARC, eliminating the need for manual memory management.
OC object to ARC to manage memory, no need to manually manage, and no memory leak:
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *aNSString = [[NSString alloc]initWithFormat:@"test"];
CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString;
aNSString = (__bridge_transfer NSString *)aCFString;
}
Copy the code
CFBridgingRelease() is the __bridge_transfer macro method. The following two lines are equivalent: aNSString = (__bridge_transfer NSString *)aCFString; aNSString = (NSString *)CFBridgingRelease(aCFString);
3.__bridge
__bridge, which does only type conversions and does not change object ownership, is the most commonly used conversion.
From OC to CF, ARC manages memory:
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *aNSString = [[NSString alloc]initWithFormat:@"test"];
CFStringRef aCFString = (__bridge CFStringRef)aNSString;
(void)aCFString;
}
Copy the code
From CF to OC, developers need to manually release, not under ARC:
- (void)viewDidLoad
{
[super viewDidLoad];
CFStringRef aCFString = CFStringCreateWithCString(NULL."test", kCFStringEncodingASCII);
NSString *aNSString = (__bridge NSString *)aCFString;
(void)aNSString;
CFRelease(aCFString);
}
Copy the code