ARC , , ARC , , :
- , (
retain) - , , (
release) - , , . ( ), , (
autorelease " release ".) 1.- , .
, , . , ARC, ARC , . , . ARC , , , , ARC; , autorelease ( ARC , ).
, , . ARC , . .
? . A NSString * a CFStringRef , ARC CF-, , ARC NSString, CFString. ARC ARC, .
CFStringRef cfstr = ...;
NSString * nsstr = (__bridge_transfer NSString *)cfstr;
"ARC, , CFString , ". , ; , cfstr , ARC , . :
NSString * nsstr = ...;
CFStringRef cfstr = (__bridge_retained CFStringRef)cftr;
"ARC, , NSString, , ". , ! - CFRelease(cfstr), .
, (__bridge ...), , . , , . , ARC , CF-, ARC , , . :
doSomethingWithString((__bridge CFStringRef)nsstr);
ARC nsstr , , , , , , , , ( , , , ARC , ).
, , , ARC- void *, API, :
- (void)doIt {
NSDictionary myCallbackContext = ...;
[obj doSomethingWithCallbackSelector:@selector(iAmDone:)
context:(__bridge_retained void *)myCallbackContext
];
}
- (void)iAmDone:(void *)context {
NSDictionary * contextDict = (__bridge_transfer NSDictionary *)context;
}
, . , :
@implementation SomeObject {
id _someIVAR;
}
- (void)someMethod {
id someValue = ...;
_someIVAR = someValue;
}
ARC ARC. ARC , ARC , :
@interface SomeObject
@property (retain,nonatomic) id someIVAR;
@end
@implementation SomeObject
- (void)someMethod {
id someValue = ...;
self.someIVAR = someValue;
}
someValue , ! -ARC :
@interface SomeObject
@property (assign,nonatomic) id someIVAR;
@end
@implementation SomeObject
- (void)someMethod {
id someValue = ...;
self.someIVAR = someValue;
}
, , ivar -ARC strong, weak, , ( ARC, __unsafe_unretained, ).
So, if you have code that uses ivars directly and does not use properties with setters / getters to access them, then switching from non-ARC to ARC can lead to code saving cycles that were used to manage reasonable memory. On the other hand, moving from ARC to non-ARC, such code can cause dangling pointers (pointers to old objects, but since the object has already died, these points and their use have unpredictable results anywhere), since the objects that were used to be alive before he can now die unexpectedly.