iOS와 OC X 멀티스레드 및 메모리 관리 (1) - 소유권 수식자와 ARC 코드 규칙

5652 단어
하나.메모리 관리의 사고방식: * 자신이 생성한 대상, 자신이 가지고 있다.iOS 생성 대상의 방법은 alloc, new,copy,mutablecopy에 대응하고 이러한 방법은 낙타봉 명명 규칙에 따라 사용자 정의된 방법으로 모두 자신이 생성했다고 볼 수 있다.eg:allocMyObject. *자신이 소지하고 있는 대상이 아니면 자신도 소지할 수 있다.retain*이 더 이상 자신이 보유한 대상이 필요하지 않을 때 방출됩니다.release*자신이 보유하지 않은 대상에 대응하여 방출할 수 없습니다.둘.autorelease 1.autorelease 성명 주기: autoreleasepool-->object를 autoreleasepool에 추가하고 -->drain autoreleasepool에 추가하며,relese 탱크의 대상입니다.2. 통과 가능objc_autoreleasePoolPrint () 는 현재 Pool의 대상 3 을 인쇄합니다.ARC의 객체 유형 소유권 수정자: 1.strong,__weak,__unsafe_unratined,__autorelease .여기서 제외unsafe_unratinded 이외의 세 개의 수식자는 수식된 변수가nil로 자동으로 초기화되는 것을 보장합니다.2.__strong, 대상에 대한 강한 인용을 표시합니다. Xcode에서 대상 형식에 소유권 수식자가 없습니다. 기본값은 입니다.strong. 예를 들면 다음과 같습니다.
NSObject *obj1 = [[NSObject alloc] init];//  retainCount 1
NSObject *obj2 = obj1;//  retainCount 2

실제로는 다음과 같다.
NSObject * __strong obj1 = [[NSObject alloc] init];//  retainCount 1
NSObject * __strong obj2 = obj1;//  retainCount 2

3.__weak, 약한 인용, 대상 실례를 가지고 있지 않습니다.当__weak 수식의 변수가 가리키는 대상이 방출될 때 변수는nil로 자동으로 설정됩니다.약한 인용은 일반적으로 인용 계수 메모리 관리 방식에 나타나는 '순환 인용' 문제를 피하는 데 쓰인다.
NSObject * __strong obj1 = [[NSObject alloc] init];//  retainCount 1
NSObject * __weak obj2 = obj1;//  retainCount   1

4.__unsafe_unretained도 약한 인용이지만 안전하지 않습니다.unsafe_retained 수식의 변수가 가리키는 대상이 방출될 때, 변수는 현수 바늘을 가리키며,crash를 초래하기 쉽다
NSObject * __strong obj1 = [[NSObject alloc] init];//  retainCount 1
NSObject * __unsafe_unretained obj2 = obj1;//  retainCount   1

5.__autoreleasing은 MRC에서 autorelease를 호출하여 대상을 autoreleasepool에 넣는 것과 같다.및strong과 마찬가지로autoreleasing은 일반적으로 두 곳에 사용됩니다.*대상을 되돌려주는 방법이 있습니다. 컴파일러는 방법 이름이 alloc/new/copy/mutablecopy로 시작되었는지 확인합니다. 자동적으로 대상을 autoreleasepool에 추가하지 않으면
- (void)customMethod {
    NSObject __strong *obj = [self getObject];
}
- (NSObject *)getObject {
    NSObject __strong *obj = [[LeeArray alloc] init];
    return obj;//  obj       ,obj       ,       release。。。    ARC       ,  Xcode      ,               
}

* 사용weak 수식 변수는 autoreleasepool에 대상을 등록합니다.왜냐하면weak 수식자는 대상의 약한 인용만 가지고 있으며, 대상을 방문하는 과정에서 대상은release에 의해 접근할 수 있습니다.eg:
NSObject * __strong obj1 = [[NSObject alloc] init];//  retainCount 1
NSObject * __weak obj2 = obj1;//  retainCount   1
NSLog(@"%@",obj2);

... 에 상당하다
NSObject * __strong obj1 = [[NSObject alloc] init];//  retainCount 1
NSObject * __weak obj2 = obj1;//  retainCount   1
NSObject * __autoreleasing temp = obj2;// weak        autoreleasepool 
NSLog(@"%@",temp);

* 객체 포인터에 값을 지정할 때, 예를 들어 NSError 객체를 일반적으로 전달하는 포인터입니다.
- (void)performOperationWithError:(NSError **)error

... 에 상당하다
- (void)performOperationWithError:(NSError * __autoreleasing *)error

이것은 메모리 관리의 사고방식에서 비롯된 것이다. alloc/new/copy/mutablecopy 방법으로 값을 되돌려받을 때 자신이 생성하고 보유한 것을 제외하고는 모두 자신이 생성하지 않았지만 자신이 보유한 것이기 때문에 대상을 autoreleasepool에 등록해야 한다.주의: 대상에게 포인터를 부여할 때 소유권 수식자는 일치해야 합니다
- (void)performOperationWithError:(NSError * __autoreleasing *)error {
    NSError * __autoreleasing pTemp1 = [[NSError alloc] init];
    NSError * pTemp2 = [[NSError alloc] init];
//    *error = pTemp1;//           
    error = &pTemp1;//        
    error = &pTemp2;//      ,pTemp2    __strong,     ,Assigning 'NSError *__strong *' to 'NSError *__autoreleasing *' changes retain/release properties of pointer
}

4: ARC에서 코드 규칙 작성 1.retain/release/retainCount/autorelease를 사용할 수 없습니다.객체 참조 수를 보려면 coreFoundation 프레임에서 CFGetRetainCount()를 사용합니다.2. 메모리 관리 방법의 명칭 규칙을 준수해야 한다(이것은 중점이며 컴파일러 코드 삽입과 관련이 있다).MRC와 마찬가지로 alloc/new/copy/mutable Copy/init (init는 ARC에만 적용) 는 상기 이름으로 시작하는 방법으로 대상을 되돌릴 때 호출자가 가지고 있어야 할 대상에게 되돌려줍니다.3. autorelepool을 만들 때 @autorelepool을 사용할 수 있습니다. 예를 들어 대량의 임시 변수가 발생하는 순환 중입니다.
for (int i = 0; i < 10000; i ++)
    {
        @autoreleasepool
        {
            //         ,               ,     autoreleasepool
            NSObject *pObj = [[NSObject alloc] init];
            NSLog(@"%@",pObj);
        }
    }

4. 객체 변수는 C 언어 구조체의 멤버가 될 수 없으며 컴파일러가 오류를 보고합니다.이는 C 언어의 규약상 구조체 구성원의 생존 주기를 관리할 방법이 없고 ARC는 메모리 관리 업무를 컴파일러에 분배하기 때문에 컴파일러는 반드시 대상의 생존 주기를 알고 관리해야 한다. 예를 들어 C 언어의 자동 변수는 이 변수의 작용역 관리 대상을 사용한다.구조체 구성원에 대상형 변수를 추가하려면void*로 강제로 변환하거나 을 사용하십시오unsafe_코스메틱 변수 5.변환void * 및 id를 표시합니다.세 개의 수식자 변환bridge,__bridge_transfer,__bridge_retained.여기서bridge는void*와 id를 수식할 수 있고, 수식void*는인용계수를 바꾸지 않는다(void*는alloc가 아니기 때문에 방출하지 않아도 된다. 컴파일러는 id의 생명주기, 즉 자동 인용계수 관리를 관리한다). 수식id는 대상 인용계수 +1(void*가alloc가 있으면release, id가 대상에 대한 강한 인용, 컴파일러가 id의 생명주기를 관리한다);bridge_transfer는 id만 수식할 수 있고 인용 계수를 바꾸지 않습니다. 변환된 변수가 가지고 있는 대상은 이 변수가 변환된 목표 변수에 부여된 후에 방출됩니다. 즉, 이때 변환된 변수는 대상에게 약한 인용입니다.bridge_retained는void*를 수식하는 데 사용되며 대상 인용 계수 +1입니다.
NSObject *pObj1 = [[NSObject alloc] init];//     1
CFTypeRef pC = (__bridge void *)pObj1;//     1
NSLog(@"%zi",CFGetRetainCount(pC));
CFTypeRef pc2 = (__bridge_retained CFTypeRef)pObj1;//     2
NSLog(@"%zi",CFGetRetainCount(pc2));
NSObject *pObj2 = (__bridge_transfer NSObject *)pC;//     2,    pC,
NSLog(@"%zi",CFGetRetainCount(pC));
NSObject *pObj3 = (__bridge NSObject *)pC;//     3
NSLog(@"%zi",CFGetRetainCount(pC));

void *와 id 간 변환 API 2개, CFTypeRefNullable CFBridgingRetain(id Nullable X) 및 idNullable CFBridgingRelease(CFTypeRef CF CONSUMED Nullable X), 사실은bridge_retained 및bridge_transfer 5: 속성과 수식자
21513169399_.pic_hd 2.jpg
6:배열

좋은 웹페이지 즐겨찾기