30. ARC로 참조 개수 단순화

5016 단어
《고품질 iOS와 OS X 코드를 작성하는 52가지 효과적인 방법》-제5장 제30조(ps: 이것은 독서노트입니다. 기억을 깊이 있게 하고 참고만 제공)

제30조 ARC로 인용 수를 간소화


ARC를 사용할 때 인용 계수는 실제로 실행되어야 한다는 것을 반드시 기억해야 한다. 단지 보류와 방출 작업은 현재 ARC에서 자동으로 추가되어 있을 뿐이다.
ARC는 Retain, release, autorelease 등을 자동으로 실행하기 때문에 ARC에서 이러한 메모리 관리 방법을 직접 호출하는 것은 불법입니다.
  • retain
  • release
  • autorelease
  • dealloc

  • 실제로 ARC는 이러한 방법을 호출할 때 일반적인 Objective-C 메시지 발송 메커니즘을 통과하지 않고 기본 C 언어 버전을 직접 호출한다.이렇게 하면 성능이 더욱 좋다. 보존 및 방출 작업이 빈번하게 실행되어야 하기 때문에 하부 함수를 직접 호출하면 많은 CPU 주기를 절약할 수 있다.예를 들어, ARC는 retain과 같은 값의 기본 함수인 objc-reatin을 호출합니다.이것도retain,release, 또는 autorelease를 다시 쓸 수 없는 이유이다. 왜냐하면 이런 방법은 직접적으로 호출되지 않기 때문이다.

    ARC 사용 시 따라야 하는 방법 명명 규칙


    메소드 이름이 다음 단어로 시작되면 반환된 값의 객체는 호출자에게 귀속됩니다.
  • alloc
  • new
  • copy
  • mutableCopy

  • 호출자의 모든 뜻은 상기 네 가지 방법을 호출한 그 코드는 방출 방법이 되돌아오는 대상을 책임져야 한다는 것이다.만약 다른 대상이 이 대상을 보존하고 autorelease를 호출한다면 보존 계수 값이 1보다 클 수 있습니다. 이것도retainCount 방법이 그다지 유용하지 않은 이유 중 하나입니다.
    ARC는 명명 규칙을 통해 메모리 관리 규칙을 표준화합니다.
    ARC는 수동 작업이 어렵고 심지어 완성할 수 없는 최적화도 실행할 수 있다.ARC는 동일한 객체에서 보존 및 해제 작업을 두 번 이상 수행한 경우 두 작업을 쌍으로 제거할 수도 있습니다.
    ARC에는 런타임 구성 요소도 포함됩니다.앞에서 말했듯이 어떤 방법은 대상을 되돌리기 전에 autorelease 작업을 실행했고, 호출 방법의 코드는 되돌아오는 대상을 보존해야 할 수도 있다. 예를 들어:
    EOCPerson * tmp = [EOCPerson personWithName:@"Bob Smith"];
    _myPerson = [tmp retain];
    

    "personWithName:"방법의 autorelease와 상단 코드의retain은 모두 불필요합니다.그러나 ARC 환경에서 코드를 컴파일할 때는 ARC에 적용되지 않는 코드를 호환하기 위해'백워드 컴파일러'(backward compatibility)를 고려해야 한다.
    그러나 ARC는 운행 기간에 이 불필요한 조작, 즉 autorelease와 그 뒤를 따르는retain을 검출할 수 있다.코드를 최적화하기 위해 방법에서 자동으로 방출된 대상을 되돌릴 때 특수 함수를 실행해야 한다.이 때 대상의 autorelease 방법을 직접 호출하지 않고objc 를 호출합니다autoreleaseRetainValue.이 함수는 현재 방법이 되돌아온 후에 실행할 코드를 검사합니다.그 코드가 되돌아오는 대상에서retain 작업을 수행하는 것을 발견하면 전역 데이터 바이트 후 (이 데이터 구조의 구체적인 내용은 프로세서에 따라 다르다) 의 표지 위치를 설정하고 autorelease 작업을 실행하지 않습니다.이와 비슷하다. 만약 방법이 자동으로 방출된 대상을 되돌려주고 호출 방법의 코드가 이 대상을 보존한다면, 이때retain을 직접 실행하지 않고 objc 를 실행하는 것으로 바뀐다.retainAutoreleasedReturnValue 함수이 함수는 방금 언급한 로고 위치를 검사해야 합니다. 위치를 설정하면retain 동작을 실행하지 않습니다.이것은 autorelease와retain을 호출하는 것보다 로고 위치를 검사합니다.
    다음 코드에서는 ARC가 이러한 특수 함수를 사용하여 프로그램을 최적화하는 방법을 보여 줍니다.
    - (EOCPerson *)personWithName:(NSString *)name
    {
        EOCPerson * person = [[EOCPerson alloc] init];
        person.name = name;
        objc_autoreleaseReturnValue(person);
        return nil;
    }
    EOCPerson *tmp = [EOCPerson personWithName:@"Matt Galloway"];
    _myPerson = objc_retainAutoreleasedReturnValue(tmp);
    

    위조 코드는 다음 단계를 설명합니다.
    id objc_autoreleaseReturnValue(id object)
    {
        if (/* caller will retain object */) {
            set_flag(object);
            return object;  ///No autorelease
        }else
        {
            return [object autorelease];
        }
    }
    
    id objc_retainAutoreleaseReturnValue(id object)
    {
        if (get_flag(object)) {
            clear_flag(object);
            return object;  ///No retain
        }else
        {
            return [object retain];
        }
    }
    

    변수의 메모리 관리 의미


    응용 프로그램에서 다음 수정자를 사용하여 로컬 변수와 인스턴스 변수의 의미를 변경할 수 있습니다.
  • __string: 기본 의미입니다. 이 값을 보존합니다.
  • __unsafe_retained: 이 값을 보류하지 않습니다. 이렇게 하면 안전하지 않을 수 있습니다. 변수를 다시 사용할 때 대상이 회수되었을 수도 있습니다.
  • __weak: 이 값을 보류하지 않지만 변수는 안전하게 사용할 수 있습니다. 시스템이 이 대상을 회수하면 변수도 자동으로 비워지기 때문입니다.
  • __autoreleasing: 대상을 '인용에 따라 전달' (pass by reference) 방법으로 전달할 때 이 특수한 수식자를 사용합니다.이 값은 방법이 되돌아올 때 자동으로 방출됩니다.

  • 우리는 자주 국부 변수에 수식자를 붙여서 블록 (block) 이 도입한 보존 고리를 깨뜨린다.블록은 자신이 캡처한 모든 객체를 자동으로 유지합니다. 그 중 하나가 블록 자체를 유지한 경우 "루프 유지"로 이어질 수 있습니다. 사용 가능weak 국부 변수로 이런'보존링'을 깨뜨리다

    ARC에서 인스턴스 변수를 클린업하는 방법


    ARC를 사용한 후에는 강력한 인용을 방출하는 dealloc 방법을 더 이상 작성할 필요가 없습니다.ARC는 Objective-C++의 특성을 빌려 청소 루틴(cleanup routine)을 생성하기 때문입니다.Objective-C++ 대상을 회수할 때, 회수할 대상은 모든 C++ 대상의 분석 함수 (destructor) 를 호출합니다.컴파일러가 어떤 대상에 C++ 대상이 포함된 것을 발견하면 이름이 생성됩니다.cxx_destruce 방법입니다.ARC는 이 기능을 이용하여 메모리 정리에 필요한 코드를 생성한다.
    그러나 Objective-C가 아닌 대상, 예를 들어CoreFoundation의 대상이나malloc()가 무더기에 분배된 메모리가 있다면 정리가 필요합니다.그러나 원래의 말과 양처럼 초종류의 dealloc 방법을 사용할 필요는 없다.ARC가 자동으로.cxx_Destruct 방법에서 코드를 생성하고 이 방법을 실행하며, 생성된 코드에서 클래스를 초과한 dealloc 방법을 자동으로 호출합니다.ARC 환경에서 dealloc은 다음과 같이 쓸 수 있습니다.
    - (void)dealloc
    {
        CFRelease(_coreFoundationObject);
        free(_heapAllocatedMemeoryBlob);
    }
    

    ARC는 회수 대상이 실행될 때 실행하는 코드를 자동으로 생성하기 때문에 dealloc 방법을 더 이상 작성할 필요가 없습니다.프로젝트 소스 코드의 크기를 줄일 수 있을 뿐만 아니라, 그 중 일부 샘플 코드 (boilerplate code) 도 줄일 수 있다.

    요점

  • ARC가 생기면 프로그래머는 메모리 관리 문제를 걱정할 필요가 없다.ARC를 사용하여 프로그래밍을 수행하면 클래스에서 많은 템플릿 코드가 제거됩니다.
  • ARC 관리 대상의 생명기간을 관리하는 방법은 기본적으로'보존'과'방출'조작을 적절하게 삽입하는 것이다.ARC 환경에서 변수의 메모리 관리 의미는 수식자를 통해 설명할 수 있지만 원래는 수동으로 '보존' 과 '방출' 작업을 실행해야 한다.
  • 방법이 되돌아오는 대상의 메모리 관리 의미는 항상 방법명을 통해 나타난다.ARC는 이를 개발자가 지켜야 할 규칙으로 결정합니다.
  • ARC는 Objective-C 객체의 메모리만 관리합니다.특히 CoreFoundation 대상은 ARC가 관리하지 않기 때문에 개발자는 적시에 CFRetain/CFRelease를 호출해야 한다.
  • 좋은 웹페이지 즐겨찾기