ARC'de a'dan NSString
bir almanın doğru yolunu anlamaya çalışıyorum CFStringRef
? Ters yöne giden için aynı CFStringRef
etmek NSString
ARC içinde?
Bellek sızıntıları oluşturmadan bunu yapmanın doğru yolu nedir?
ARC'de a'dan NSString
bir almanın doğru yolunu anlamaya çalışıyorum CFStringRef
? Ters yöne giden için aynı CFStringRef
etmek NSString
ARC içinde?
Bellek sızıntıları oluşturmadan bunu yapmanın doğru yolu nedir?
retain
ing ve release
nesneleri -ing, şimdiki gibi "güzel" atmalarını kullanmalıdır __bridge_transfer
, __unsafe_unretained
ve __autoreleasing
. Kimsenin buna vakti yok. (Ve cidden, okumak daha zor. Bence bellek yönetimini hiç kolaylaştırmadı.)
Yanıtlar:
Tipik
NSString *yourFriendlyNSString = (__bridge NSString *)yourFriendlyCFString;
ve
CFStringRef yourFriendlyCFString = (__bridge CFStringRef)yourFriendlyNSString;
Şimdi, __bridge
anahtar kelimenin neden orada olduğunu bilmek istiyorsanız , Apple belgelerine bakabilirsiniz . Orada bulacaksın:
__bridge
Mülkiyet devri olmaksızın Objective-C ve Core Foundation arasında bir işaretçi aktarır.
__bridge_retained
veyaCFBridgingRetain
bir Core Foundation işaretçisine bir Objective-C işaretçisini atar ve ayrıca sahipliği size aktarır. Nesnenin sahipliğinden vazgeçmek için CFRelease'i veya ilgili bir işlevi aramaktan sorumlusunuz.
__bridge_transfer
veyaCFBridgingRelease
Objective-C olmayan bir işaretçiyi Objective-C'ye taşır ve sahipliği ARC'ye aktarır. ARC, nesnenin sahipliğinden vazgeçmekten sorumludur.
Bu, yukarıdaki durumlarda, sahipliği değiştirmeden nesneyi yayınladığınız anlamına gelir. Bu, her iki durumda da dizelerin belleğini idare etmekten sorumlu olmayacağınız anlamına gelir.
Ayrıca, herhangi bir nedenle mülkiyeti devretmek istediğiniz durum da olabilir.
Örneğin aşağıdaki pasajı düşünün
- (void)sayHi {
CFStringRef str = CFStringCreateWithCString(NULL, "Hello World!", kCFStringEncodingMacRoman);
NSString * aNSString = (__bridge NSString *)str;
NSLog(@"%@", aNSString);
CFRelease(str); //you have to release the string because you created it with a 'Create' CF function
}
böyle bir durumda CFRelease
, yayın yaparken sahipliği devrederek bir kaydetmek isteyebilirsiniz .
- (void)sayHi {
CFStringRef str = CFStringCreateWithCString(NULL, "Hello World!", kCFStringEncodingMacRoman);
NSString * aNSString = (__bridge_transfer NSString *)str;
// or alternatively
NSString * aNSString = (NSString *)CFBridgingRelease(str);
NSLog(@"%@", aNSString);
}
Mülkiyeti str
aktarıldı, bu yüzden şimdi ARC devreye girecek ve hafızayı sizin için serbest bırakacak.
Eğer bir yayın yapabiliyorsa etrafındaki diğer Yolda NSString *
bir karşı CFString
bir kullanarak __bridge_retained
nesneyi sahibi olacak ve açıkça kullanarak bırakın gerekecek, böylece döküm CFRelease
.
Sarmak için sahip olabilirsin
// Don't transfer ownership. You won't have to call `CFRelease`
CFStringRef str = (__bridge CFStringRef)string;
// Transfer ownership (i.e. get ARC out of the way). The object is now yours and you must call `CFRelease` when you're done with it
CFStringRef str = (__bridge_retained CFStringRef)string // you will have to call `CFRelease`
// Don't transfer ownership. ARC stays out of the way, and you must call `CFRelease` on `str` if appropriate (depending on how the `CFString` was created)
NSString *string = (__bridge NSString *)str;
// Transfer ownership to ARC. ARC kicks in and it's now in charge of releasing the string object. You won't have to explicitly call `CFRelease` on `str`
NSString *string = (__bridge_transfer NSString *)str;
NSString->CFString
kullanmalıyız __bridge
. ama ne zaman CFString->NSString
kullanmalıyız __bride_transfer
. ? Ve CFRelease
ihtiyacımız olmadığında kullanırsak herhangi bir yan etki . teşekkürler :)
CFRelease
, programınızı makul bir şekilde çökertmelidir, çünkü uyumsuz tut / bırak işlemiyle sonuçlanacak ve sonunda bir NULL
işaretçi bırakacaksınız .
CFStringRef foo (__bridge CFStringRef)theNSString;
veNSString *bar = (__bridge NSString *)theCFString;