ARC 및 비 ARC 하oc 객체 및 CF 객체 변환
5132 단어 Objective-C메모리 유출CoreFundation
1. 매크로를 사용하면 귀속자가 OC에서 CF로 갈지, 아니면 CF에서 OC로 갈지 표시할 수 있다.
NS_INLINE CFTypeRef CFBridgingRetain(id X) {
return (__bridge_retain CFTypeRef)X;
}
NS_INLINE id CFBridgingRelease(CFTypeRef X) {
return (__bridge_transfer id)X;
}
2. 전환부호를 사용한다. 예를 들어bridge,__bridge_transfer,__bridge_retained
__bridge: 대상의 모든 관계 변화와 관련이 없습니다
__bridge_transfer: ARC 소유권 부여
__bridge_retained: ARC 소유권 해제
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
ARC 이외의 모드:
#pragma mark – View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"=%@", [self escape:@"LIN986LIN"]);
}
-(NSString *)escape:(NSString *)text
{
return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL, (__bridge CFStringRef)text,NULL,CFSTR("!*’();:@&=+$,/?%#[]"), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
}
ARC 모드:
위의 함수를 다음과 같이 자동으로 변환하는 xcode를 볼 수 있습니다.
#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));
}
arc에서 CF와 OC 간의 전환교량은bridge, 두 가지 방법이 있습니다.__bridge_transfer ARC 관리 메모리
__bridge_retained ARC 메모리 관리 해제
oc에서 CF로의 전환은 OC의 메모리 관리권을 방출해야 한다.
NSString *str = [[NSString alloc] initWithFormat:@"Welcome , %@!", name];
CFStringRef strref = (__bridge_retained CFStringRef)str;
// do something with strref
CFRelease(strref);
마지막으로 CF가 메모리를 방출합니다.위 코드는 다음과 같습니다.
CFStringRef strref = CFBridgingRetain(str);
// do something with strref
CFRelease(strref);
CF가 OC로 전환되고 객체의 소유자가 변경되면 CFBridgingRelease() 또는bridge_transfer . OC가 CF로 전환되고 객체의 소유자가 변경되면 CFBridgingRetain() 또는bridge_retained
한 유형이 다른 유형으로 전환되지만 대상 소유자가 바뀌지 않으면 을 사용합니다bridge.
CF 객체와 OC 객체를 혼용하면 발생할 수 있는 문제:
ARC 모드에서 자동 회수는 Objective-C 대상에게만 유효하며, Core Foundation 대상에 대해서는 저희가 수동으로 방출해야 합니다. CFRelease().
다음 상황을 분석합니다.
하나의 방법으로 CGColorRef 객체 정의: CGColorRef cf
각각 다음과 같은 세 가지 방식을 통해 cf에 값을 부여한 후 cf를 사용할 때 어떤 차이가 있을까요?
방법 1:
UIColor* color = [[UIColor alloc] initWithRed:0.0f green:0.0f blue:0.0f alpha:1.0f];
cf = color.CGColor;
방법2:cf = [[UIColor alloc] initWithRed:0.0f green:0.0f blue:0.0f alpha:1.0f].CGColor;
방법3:cf = [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:1.0f].CGColor;
방식 1과 방식 3은 운행에 문제가 없다.방식 2 다음에 cf를 사용하면 crash를 할 수 있습니다. 왜냐하면 이때 cf는 이미 야외 지침이기 때문입니다.분석은 다음과 같습니다.
방식1에서 color 대상은 기본적으로strong강인용으로 이 방법의 생명주기 내에 모두 유효하며, 이 방법을 종료할 때 자동으로 풀에 방출됩니다.그래서 그 CGColor로 하는 건 문제 없어요.
방식 3은 유사합니다. colorWithRed:... 이것은 클래스입니다. autorelease 대상을 되돌려줍니다. 대상은 자동으로 풀을 풀기 전에 모두 유효하기 때문에 문제가 발생하지 않습니다.
방식2에서 생성된 UIColor 대상은 어떤 owner에게도 주지 않았고 weak의 약한 인용에 해당하며 alloc는 그 후에 바로 방출되었다. 그래서 그의 CGColor 변수도 이에 따라 야생 지침이 되었다.
ARC 아래 OC 객체가 CF 객체와 브리지됩니다.
다음 코드 행:
CFStringRef s1 = (CFStringRef)[[NSString alloc] initWithFormat:@”Hello, %d!”, 1];
ARC 아래에 컴파일 문제가 보고되고 권장 솔루션이 제공됩니다.CFStringRef s1 = (__bridge CFStringRef)[[NSString alloc] initWithFormat:@”Hello, %d!”, 1];
여기서 NSString은 OC의 대상을 생성하고 메모리는 ARC가 책임진다.s1은 CF의 대상이며, 메모리는 스스로 수동으로 관리해야 한다.두 변수가 변환될 때 브리지 표식을 추가해야 합니다.위의 경우 Crash도, 메모리 유출도 없습니다.alloc에서 나온 메모리는 ARC에서 회수되기 때문에 이 메모리의 모든 관계는 변하지 않습니다.
뒤에 CFRelease(s1)가 붙으면이 메모리는 ARC가 관리하기 때문에 과도하게 방출될 수 있다.
수정:
CFStringRef s1 = (__bridge_retained CFStringRef)[[NSString alloc] initWithFormat:@”Hello, %d!”, 1];
이 경우 대상의 소유권은 CF 대상에게 넘어간다.CFRelease(s1)를 추가해야 합니다.석방을 진행하지 않으면 누설이 발생할 수 있다.
다음 코드를 다시 보십시오.
CFUUIDRef uu = CFUUIDCreate(NULL);
CFStringRef s2 = CFUUIDCreateString(NULL, uu);
CFRelease(uu);
NSString* str = (__bridge NSString*)s2;
NSLog(@”STR:%@”,str);
CFRelease(s2);
이곳의 u와 s2는 모두 CFRelease를 사용하여 방출해야 한다. 왜냐하면 그들은 OC 대상이 아니고create에서 나온 메모리이며 소유권이 방출되지 않았기 때문이다.다음 코드를 변경하면
NSString* str = (__bridge_transfer NSString*)s2;
이 때 프로그램을 실행하면crash를 일으킬 수 있습니다. s2의 소유권은 ARC의str에 맡겼기 때문에 ARC는 이 메모리를 방출하는 것을 책임집니다.
이때 CFRelease(s2)를 호출합니다.과도한 석방을 초래할 수 있다.그래서 이 업종을 대행해야 한다.
참고:
ARC 모드에서는 Objective-C 대상만 자동 회수가 유효하며,create,copy,retain 등을 사용하여 생성된CoreFoundation 대상은 우리가 수동으로 방출해야 합니다.CFRelease().
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
PreferenceBundle에서 오른쪽 상단에 Respring 버튼을 클릭합니다.만나서 반갑습니다, Minazuki라고합니다. 프로필 이름 : Minazuki_dev Twitter : Repo : 아직 중학생이므로 말이 이상한 곳이 있습니다만 용서해 주세요… 🙏 theos (Mac이든 단품이든 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.