iOS 메모리 관리: 참조 계수, ARC, 자동 방출 탱크autoreleasepool과 편리한 방법 간의 관계

일부 내용은'Objective-C 기초 강좌'와 인터넷에서 발췌한 것이다.ARC 섹션은 여기를 참조하십시오.

참조 개수


코코아는 인용 계수(reference counting) 메커니즘을 채택하여 모든 대상에 연결된'정수retainCount'을 사용하여 대상의 사용 상황을 기록한다.대상이 인용되었을 때retaincount+1, 외부 환경이 끝난 후에retainCount-1.retaincount가 0일 때, 이 대상은 소각됩니다.
alloc, new,copy를 사용하는 경우 이 대상을 없애야 합니다.release 함수, 대상의retainCount 값을 1로 줄일 뿐, 대상을 삭제하는 것이 아닙니다.retainCount==0일 때 시스템은 대상에게 dealloc 메시지를 보냅니다. 또한 수동으로 dealloc를 호출하지 마십시오. 왜냐하면 우리는 언제, 어디서, 누가 이 대상을 사용할지 모르기 때문입니다.인용 계수 메커니즘에 성실하게 의존하여 메모리 관리를 완성해야 한다.
대상의 소유권을 방출하는 함수는release를 제외하고autorelease도 있는데 이것은 일종의 지연 작업이다. 다음에 상세하게 소개할 것이다.
다음 코드를 보았을 때 첫 번째 질문은dateformatter의 메모리 관리입니다. [NSDateFormatter alloc] 때문에release를 사용해야 합니다.강조 코드 주의
-(NSString*) date2String:(NSString*)str{
   NSString* dateString;
   NSDate *  currentTime=[NSDate date];
    NSDateFormatter  *dateformatter=[[NSDateFormatteralloc]init];
    [dateformatter setDateFormat:str];
    dateString =[dateformatter stringFromDate:currentTime];
    [dateformatterrelease];
    return dateString;
}
그럼 이 함수 중의
NSString
* dateString 및
NSDate * currentTime 두 변수의 메모리 관리 방법그리고
dateString은 되돌아오는 값으로 메모리 관리는 어떻습니까?이것은 좋은 문제다.
우리는dateString의 값을 부여하는 방법이 [dateformatterstringFromDate:current]라는 것을 발견했다. 분명히 이것은 alloc, new,copy의 어떤 것도 사용하지 않았다.Objective-C 기초 강좌에 의하면,dateString 대상이 되돌아올 때 인용 계수 값이 1이라고 가정합니다.허허,'가정'이라는 두 글자.이 책은 정말 기초 교과 과정이다!
방금 《Objective-C 기초 강좌》에서 말했듯이 OC에는 창고 대상이 없고 임시 대상이 없다.그럼 이 데이트스트링은 뭐예요?
그러면 이제 그들을 자동으로 방출하는 범주에 넣으면 다음과 같이 이해할 수 있다. [dateformatter string FromDate:current] 안에 alloc의 새로운 대상.이 대상은 autorelease의 것이다.
자동 해제는 아래에 자세히 설명되어 있습니다.

자동 방출 탱크autoreleasepool


자동 풀은 NSAutoreleasePool의 인스턴스로, autorelease 메시지를 받는 객체가 포함됩니다.자동 방출 탱크 자체가 소각될 때 (dealloc), 탱크의 모든 대상에게release 메시지를 보냅니다. (만약 한 대상에게 autorelease 메시지를 여러 번 보낸다면, 자동 방출 탱크가 소각될 때, 이 대상도 같은 수의release 메시지를 받을 수 있습니다.)자동 방출 대상은 적어도 자동 방출 탱크가 소각될 때까지 살아남을 수 있다는 것을 알 수 있다.간단하게 말하자면, 부분적으로 변수를 쌓아 놓은 바늘을 되돌려줍니다. (c++의 말투로 말했습니다.) 그러면 이 대상은 어떻게 방출합니까?Objective-C는 자동 방출 메커니즘을 발명했다.
-(obj*) foo
{
obj* temp = [[obj alloc]init];
return [ obj autorelease];// autorelease
}

Objective-C 기초 강좌에 따르면 자동 방출(autorelease)은 일종의 지연 방출 메커니즘으로 국부 더미의 변수가 외부에서 정상적으로 사용될 수 있도록 보장한다.
그러나 시스템은 언제 풀렸을까?모든 이벤트 주기(event cycle)의 시작에 시스템은 자동으로 자동 방출 탱크를 만들 것이다.
모든 이벤트 주기의 끝에 시스템은 자동으로 이 자동 방출 탱크를 소각할 것이다.일반적인 상황에서 당신은 다음과 같이 이해할 수 있다. 당신의 코드가 지속적으로 운행할 때 자동 방출 탱크는 소각되지 않으며 이 기간 동안 당신은 자동 방출 대상을 안전하게 사용할 수 있다.코드가 일단락되고 사용자의 입력을 기다리기 시작할 때, 자동 방출 탱크는 방출되고, 탱크의 대상은release 메시지를 받을 수 있으며, 일부는 소각될 수도 있습니다.
이것은 확정하기 어려운 시간이다. 만약 자동 방출 탱크의 소각 시간이 너무 이르면 프로그램은 매우 위험하다. 이것은 아마도 프로그래머의 요구를 만족시키기 어려울 것이다.
자동 방출 탱크의 단점: 대상의 방출을 늦추고 대량의 자동 방출 대상이 있을 때 대량의 메모리 자원을 차지한다.따라서 대량의 대상을 자동으로 방출하는 것을 피해야 한다.그리고 다음 두 가지 상황에서 자동 방출 탱크를 수동으로 구축하고 수동으로 제거해야 한다.
1. 메인 라인 밖에서 다른 라인을 열 때: 시스템은 메인 라인에서만 자동으로 생성되고 자동 방출 탱크를 파괴합니다.
2. 짧은 시간 안에 대량의 자동 방출 대상을 만들었을 때: 아이패드에 있는 유한한 메모리 자원을 효과적으로 활용하는 데 도움이 된다.
따라서 저는 autorelease의 메커니즘을 사용하는 것을 권장하지 않습니다. 만약에 상기 예의 상황에 부딪히면 전형적인 해결 방법을 사용하십시오. 외부의 한 대상은obj대상을 삭제하고 메모리 유출을 방지합니다.

Convenience method 메모리 관리


자동 방출과 관련된 큰 구조 방법(constructor method)이 있는데 그것들이 구성하는 대상은 바로 자동 방출의 대상이다.이런 구조 방법을 편리한 방법이라고 한다.예를 들어 아래의 문자열은 자동으로 방출되는 대상이고stringWithFormat: 편리한 방법이다.
NSString* string = [NSString stringWithFormat:@”autoreleaseString”];
몇 가지 편리한 방법의 예를 들어 독자의 향후 개발을 편리하게 하다.
1. NSArray의 array WithObjects: 및 array WithArray:.
2. UIImage의 imageNamed:.
3. NSNumber의 numberWithBool 등.즉, 이러한 방법이 되돌아오는 대상은 우리가 사용할 수 있지만, 그녀가 언제 dealloc를 돌아올지 확실하게 알 수는 없다. 그러면 우리는 이러한'편리함수'가 되돌아오는 대상을 자발적으로 삭제할 수 있을까?만약 프로그램에 대량의 '편리 함수' 가 있다면, 이것은 의심할 여지없이 대량의 메모리 공간을 차지할 것이다.
설마 이런 편리한 함수를 순환적으로 호출하는 것을 피할 수 있을 뿐인가?
현재 우리는 autorelease 방법이 일정 시간 후에 대상을 방출하고 이 시간 안에 우리는 이 대상을 안전하게 사용할 수 있다고 설명했다.그렇다면 이 시간은 얼마나 걸릴까요?
위에서 이미 자동 방출 메커니즘을 소개했는데'편리 함수'가 발생하는 대상은 적어도 자동 방출 탱크가 소각될 때까지 살아남을 수 있다.

ARC(Auto Reference counting)


위의 글은 '인용 계수' 를 소개했고, 여기에는 더욱 높은 자동 인용 계수가 나왔다.
이 문장을 참고하시오http://blog.csdn.net/zkdemon/article/details/7446385
/***************************************** 다음은 일반적인 응용***********************************?

self.xxx의 역할.


    NSInteger i =0;
첫 줄extraMessage = [[FtExportMessagealloc]init];
두 번째 줄//self.extraMessage = [[FtExportMessage alloc]init];
    i = [self.extraMessageretainCount];
    [self.extraMessagerelease];
첫 줄을 실행할 때retainCount가 1이라는 것을 알 수 있습니다. 이것은 이해하기 쉽습니다.그러나 두 번째 줄 코드를 사용하지 마십시오.retaincount는 2입니다. 이럴 때release를 호출해도 대상을 삭제하지 않습니다.
초보자는 실수를 하기 쉬워서 어디든self를 사용한다.XXX.

NSArray 및 NSDictionary 추가 요소, 메모리 관리


이런 집합 클래스는 단지 원소의retainCount에 1을 더할 뿐이다.마찬가지로 NSDictionary release에서는 요소를
- (void)prepareData{
    _buddyMsg   = [[ExportMsgEntityalloc]init];
    _pgMsg      = [[ExportMsgEntity alloc] init];;
    _dgMsg      = [[ExportMsgEntity alloc] init];
    _msgGroup = [[NSMutableDictionaryalloc]initWithObjectsAndKeys:
                    self.buddyMsg,KMsgBuddy,
                    self.pgMsg,KMsgPGGroup,
                     self.dgMsg,KMsgDGGroup,nil];
   int i=0;
    i = self.buddyMsg.retainCount;//지금 i=2
}
위의 코드는self를 사용합니다.buddy Msg의retain Count는 1 더하기 1에서 2가 됩니다.그렇다면 NSDictionary가 분석된 후 다음과 같은 상황을 보십시오
- (void)deleteDictionary{
    [self.msgGrouprelease];
    int i=0;
    i = self.buddyMsg.retainCount;//지금 i=1
}
위 코드는self를 사용합니다.buddy Msg의 retain Count 는 2 에서 1 을 뺀다
총괄: 이러한'집합'을 사용할 때'집합'release를 망상하지 마세요. 안에 있는 요소가 자동으로 삭제됩니다.마지막으로 원소 자체release 자원이다.

좋은 웹페이지 즐겨찾기