2010년 12월 9일 목요일

iOS 메모리관리1(출처:맥부기)

[문씨의 강좌] 메모리 관리 | 문씨의강좌
2010.08.07 20:53
문씨(swmoon203)
카페스탭
http://cafe.naver.com/mcbugi/71504
안녕하세요 문씨입니다

이번 강좌에서는 제일 중요한 기초인 메모리 관리에 대해 다루어 보겠습니다.


본론에 들어가기 전에 Objective-C에 대해 잠시 알아보겠습니다.
*이 부분은 제 개인적인 소견이므로 잘못된 정보가 있을 수도 있습니다.

Objective-C는 C++과 마찬가지로 C에서 파생된 언어입니다.
다만 구조적 특징을 보면 C++보다 Objective-C가 좀더 C에 가깝습니다.

C++은 C에서 메모리 관리를 직접 하는 포인터 개념에 충실한 반면 Objective-C는 메모리 관리를 어느정도 대신 해주는 개념을 가지고 있습니다.

저는 Objective-C가 가장 편합니다. (그동안 많이 써서 그렇겠지만;;;) 그리고 모바일의 제한적 성능 환경에 본의 아니게 가장 어울리는 언어라고 보고있습니다.

언어를 대체적으로 C나 C++, Java, Objective-C로 세분류로 나누고 본다면
일단 C나 C++은 개발하기가 어렵습니다. 하지만 메모리 관리를 직접할수 있기 때문에 고수가 개발한다면 정말 강력한 앱을 만들수도 있습니다.
Java는 메모리 관리를 신경 안쓰는 언어입니다. 덕분에 개발은 편하죠. 다만 메모리 관리하는 가비지콜렉션 때문에 모바일 환경에서는 상당히 느립니다. 
*가비지콜렉션은 시스템상의 메모리를 전부 읽어서 안쓰는 메모리는 제거해 주는 개념입니다.

데스크탑이라면 별 의미없지만 모바일이라는 환경에서는 차이가 납니다.
그래서 직접 메모리를 관리 하는 방법 VS 가비지콜렉션으로 메모리 관리 라는 두 구도가 생성됩니다만 어느쪽이든 사용하기는 힘든 감이 있죠. 

직접 메모리 관리는 너무 개발하기 힘들고 Java는 느려서 원하는 성능을 내기가 힘듭니다.
후에 모바일 기기의 성능이 PC급으로 올라가면 얘기가 달라지겠지만요.

그렇다면 개발하기는 편하면서 가비지컬렉션을 사용하지 않는 방법은 없을까 하는 질문에 등장하는것이 Objective-C입니다.

물론 Objective-C도 가비지콜렉션은 지원합니다. 하지만 모바일 기기인 아이폰이나 터치, 아이패드 등에서는 지원하지 않습니다. 즉 OSX에서는 지원하지만 iOS에서는 지원하지 않습니다.

애플도 가비지콜렉션의 무거움을 알기때문에 일부러 지원을 안했다고 합니다.


Objective-C에서는 리테인 카운트(retain count)기법을 사용합니다. 해당 객체를 몇군데에서 사용하고 있는지 그것을 수치로 가지고 있는겁니다. 그리고 아무곳에서도 사용하지 않을때 지워지는 개념입니다.

개념만 본다면 더이상 사용하지 않는 객체를 찾아서 지우는 가비지콜렉션과 유사하기도 합니다. 다른점이라면 가비지콜렉션은 시스템에 기생해서 메모리는 체크하는 방식이지만 Objective-C는 로직으로 제거되는 방식입니다.
즉 Java에서는 객체를 쓰고 뒤처리를 안하지만 Objective-C에서는 반드시 뒤처리를 합니다.
객체를 사용후 해당 객체에게 이곳에서는 사용을 중지했다고 알려주는겁니다. 


Objective-C에서 모든 객체들의 순환(Life Cycle)을 이해 하려면 우선 NSObject를 알아야 합니다.

모든 객체는 NSObject를 상속 받았기 때문이죠. 그래서 NSObject를 알면 메모리관리를 알게 됩니다.

NSObject의 NS는 Next Step의 약자이고 Object는 말 그대로 객체를 뜻합니다.


먼저 NSObject의 헤더를 보겠습니다.

클래스 선언 부분인 @interface NSObject를 보면 최상위의 클래스 이기때문에 상속받는 부모클래스가 없습니다. 보통 @interface test : NSObject 식으로 부모클래스 선언이 반드시 있습니다. 물론 없으면 에러 경고를 띄우기도 합니다.

그리고 선언된 함수들을 보면 +와 -가 있습니다. +의 경우 클래스 함수(Class Method)라 하고 -는 인스턴트 함수(Instance Method)라 합니다. 클래스를 도장이라고 본다면 인스턴트는 도장으로 찍어서 만든 것이라 할수 있습니다. 클래스도 주소가 존재하기 때문에 객체로 취급 받기도 합니다. 물론 클래스는 단일 존재라 단 하나만 존재합니다. 그리고 인스턴트는 이 클래스로 원하는 만큼 만들어 낼수가 있습니다,

그럼 예를 보겠습니다.

NSObject *object = [NSObject alloc];

object라는 변수에 NSObject라는 클래스에 alloc이라는 클래스 함수를 호출해서 새로운 인스턴트 객체를 만든후 그 객체의 주소를 object변수에 저장했습니다.

그럼 다른 예를 보겠습니다.

NSArray *array = [NSArray alloc];

array라는 객체변수에 NSArray라는 클래스에 alloc이라는 클래스 함수를 호출해서 새로운 NSArray인스턴트 객체를 만들고 그 주소를 array에 지정합니다.


객체 생성은 반드시 alloc이라는 클래스 함수를 호출해서 원하는 객체를 찍어내는 겁니다.

모든 클래스는 NSObject를 상속받고 있기 때문에 alloc함수는 어디는 존재하게 되는겁니다.



객체를 생성했으면 이번에는 초기화를 해줍니다.

NSArray *array = [NSArray alloc];
[array init];

위에 헤더에도 있는 init은 기본 초기화 함수입니다. init은 인스턴트 함수이기 때문에 객체 생성후 최초로 객체에 호출되는 함수입니다.

단 위의 코드는 문제가 있습니다. 애플의 가이드 문서도 위와 같은 사용은 금지하고 있습니다.

왜그럴까요? 

NSArray *array = [NSArray alloc]; 에서 객체를 생성한것까진 좋습니다.
문제는 [array init]; 입니다.

위 코드는 array에 init이라는 메세지만 날려줄뿐입니다.

init을 날렸는데 객체가 판단하기에 뭔가 잘못된 것이 있으면 객체가 스스로 해제 되기도 합니다.

위의 코드는 예문이라 그럴일은 절대 없지만 다른 코드에서는 그럴일도 있을수 있습니다.
init함수는 초기화가 제대로 되면 자기자신의 주소를 돌려주고 잘못되면 스스로 해제를 한 후 nil(0값)을 돌려줍니다.

즉 위의 코드는 init만 날리고 돌려주는 값에 대한 대처가 안되어 있기 때문에 array변수가 가지고 있는 객체의 주소는 쓰레기가 되어버립니다.

즉 
NSArray *array = [NSArray alloc];
array = [array init];
아니면
NSArray *array = [[NSArray alloc] init];
을 사용합니다

결국 코드의 간결화를 위해 후자를 사용하게 됩니다.



이제 초기화를 했으면 해제를 해야합니다.

NSObject헤더에 인스턴트 함수중에 release와 autorelease가 있습니다.
autorelease는 잠시 후에 다루고 일단 release부터 봅니다.

만든 객체에 release를 날려주면 객체는 해제가 됩니다.

[array release];




단 여기서 많은 분들이 해매는 개념이 있습니다. 저 또한 이해하기 전까진 많이 해맸습니다.

release는 객체를 완전히 제거하는 명령이 아닌 단순히 이곳에서는 이 객체를 더이상 쓰지 않는다고 알려주는 함수입니다.

NSObject에는 객체를 생성하는 함수는 있지만 완전 제거하는 함수는 존재하지 않습니다.
C에서 본다면 free문이 없다는 것입니다.


대신 NSObject에는 retainCount라는 개념이 있습니다. 

alloc으로 처음 생성될때 1이라는 수치로 시작됩니다.
그리고 release라는 함수가 호출되면 내부에 retainCount를 하나 줄입니다.
위와 같은 경우는 1에서 하나 줄어서 0이 됩니다.
그러면 객체는 자동으로 메모리 상에서 제거가 됩니다.

NSArray *array = [[NSArray alloc] init]; //1
[array release]; //0

Objective-C에서 메모리 누수란 이 retain count가 0이 안되고 남아있어서 벌어지는 문제입니다.

그러면 release가 있으니 반대도 있습니다.
retain이라는 함수가 그 반대 역활을 합니다.

NSArray *array = [[NSArray alloc] init]; // 1
[array retain]; //2
[array release]; //1
[array release]; //0

리테인 카운터의 개념 및 규칙은 “올린만큼 내려라” 입니다.

간단하죠?
근데 머리로는 이해 하겠는데 정작 코딩으로 하려고 하면 다시 해맵니다.


그리고 또 autorelease는 뭐고요.
autorelease의 존재는 정말 코딩을 편하게 해주는 기능입니다.

지금 이대로 autorelease없이 코딩한다면 위와 같이 전부 객체 생성을 한후 사용이 끝난 부분에서 일일이 전부 release를 날려줘야 합니다.


코딩 하다보면 사용하는 변수가 점점 많아지는데 이것들은 언제 일일이 release하나요.

오토릴리즈(autorelease)를 사용안한다면
NSArray *array = [[NSArray alloc] init];
... 한참 사용후
[array release];
이런식으로 사용하겠지만

오토릴리즈를 사용한다면
NSArray *array = [[[NSArray alloc] init] autorelease];
...사용

그리고 사용후에는 release를 신경 쓸 필요가 없습니다. 

왠지 일일이 뒤처리 할필요가 없어진듯합니다.


마치 Java같군요.

오토릴리즈라 한다면 언젠간 자동으로 해제된다는 것인데
어떤 원리 일까요?

오토릴리즈는 편한 존재이지만 그 원리는 이해 못하기 때문에 오히려 처음 배우는 사람에게는 혼란을 일으킵니다. 

언제 해제될까? 라는 궁금증이 이 함수에 대한 신뢰를 잃게 되는것이죠
그래서 불편하더라도 확실히 생성하고 확실히 릴리즈를 날리는 코더를 많이 볼수 있었습니다.

오토릴리즈는 오토릴리즈 풀(NSAutoreleasePool)과 연결되어 있습니다.

생성된 객체에 autorelease를 날려주면 해당 객체는 자동으로 오토릴리즈 풀에 등록됩니다.

해제를 시켜주는 것이 아닌 등록입니다. 다른 말로 수영장(pool)에 빠트려 놓는것이죠

그리고 특정 시간이 지나면 그 수영장은 물을 빼고 청소를 합니다.

그때 전에 빠진것들은 다 릴리즈 처리가 되면서 해제되는 것이죠


그럼 NSAutoreleasePool이 모아서 한꺼번에 release처리해준다는 것은 알았습니다.
그러면 언제 그런일(drain)이 일어날까요?

저는 일단 프로세스가 이벤트 루프로 돌아갈때 일어난다고 보고있습니다.

앱이 실행중일때 아무것도 안하고 있다면
메인 스레드는 이벤트 루프에서 무한 루프를 돌고 있습니다.

그러다 어떠한 이벤트가 발생한다면 그 발생한 이벤트에 따라 함수를 호출합니다.
그리고 그 함수가 끝나면 다시 이벤트 루프로 돌아옵니다.

그리고 실행된 함수는 혼자서 일하고 끝나기도 하지만 작업을 위해 함수가 다른 함수를 부르는 일이 반드시 생깁니다.

예를 하나 들겠습니다.

이벤트 루프에서 돌고 있다가 유저가 화면에 터치 했습니다.

그러면 이벤트 루프는 UIApplication객체에 터치 이벤트가 있음을 알리는 메세지를 날립니다. 
*보통 Objective-C에서 메세지를 날린다고 하면 해당 객체에 함수를 호출한다고 보면 됩니다.

그럼 앱은 최상위 화면인 UIWindow에 메세지를 보내고
UIWindow는 위에 올려진 뷰에 메세지를 보낼것이고
올려진 뷰는 올려진 뷰위에 올려진 뷰에 메세지를 보내서
가장 상단에 올려진 뷰까지 메세지가 갔다올것입니다.

즉 함수가 함수를 호출하는 상황입니다.

그래서 그사이에 생성되는 오토릴리즈된 객체들은 해제되지 않고 있다가
일을 마치고 이벤트 루프로 돌아오면 전부 해제 처리되는겁니다.


결국 함수내에서 autorelease시킨 객체들이 함수 진행도중 해제 될까봐 걱정할 일은 없습니다.



그럼 하나의 함수내에서 만들어 쓰고 버리는 객체들은 release를 사용할 일이 없겠군요.
전부 오토릴리즈로 처리하면 되니까요. 

그렇습니다. 근데 더 편하게 쓰게 도와주는것들이 있습니다.


NextStep시절부터 개발되어 오던 모든 클래스들은 한가지 규칙을 지키고 있습니다.

“객체를 돌려주는 함수는 반드시 오토릴리즈된 객체를 돌려준다”는 것입니다. 


위에서 언급했던 클래스 함수들.
 
한가지 예를 들어보죠.

NSArray *array = [[[NSArray alloc] init] autorelease];

저처럼 [[[ <- 이거에 익숙해진 분들이라면 별 문제 없겠지만 이것들이 많아진다면 그것도 나름데로 스트레스입니다. NSArray같은 경우는 array라는 클래스 함수를 제공합니다. 함수로 돌려주는 객체는 반드시 오토릴리즈 된 객체이다 라는 규칙을 따르기 때문에 NSArray *array = [NSArray array];  이 코드는 위의 alloc init autorelease를 사용한 코드와 같은 의미 입니다. 이렇게 기본적으로 Foundation에 내장되어 있는 NS계열의 객체들이나 아이폰부터 추가된 UIKit등 모든 클래스들이  alloc이 아닌 특별히 제공하는 클래스 함수들은 전부 오토릴리즈 된 객체를 생성합니다. 제가 몇번 봐드린 코드 중이 이런 코드도 있었습니다. 1: NSString *str = [[NSString alloc] initWithString:@”test”]; 2: str = [str uppercaseString]; 3: [str release]; 이러면 에러가 나고 튕긴다는 문제였습니다. 1에서 오토릴리즈 안된 객체를 생성합니다. 2에서  str에 기존의 문자열을 대문자로 바꾼 새로운 개체를 돌려주는 함수를 실행해서 돌려준 새로운 오토릴리즈된 객체의 주소를 다시 str에 지정합니다. 이시점에서 기존의 str객체의 주소를 잃어버리게 되는겁니다. 당연 메모리 누수가 납니다. 그리고 str는 전부 대문자로 변환된 새로운 객체를 가지고 있게 됩니다 하지만 오토릴리즈된 객체라 3에서 release를 날리면 당연 문제가 됩니다. 여기서 놓친 부분은 uppercaseString함수가 새로운 오토릴리즈된 객체를 만들어서 돌려준다는 점입니다.  그럼 alloc의외에 클래스 생성 함수에 의해 만들어지는 객체들은 전부 오토리리즈된 객체란것은 알았습니다. 그런데 아직도 이해가 안되는 부분이 있습니다. NSArray같은 데이터 관리 객체는 어떻게 하나요? NSArray보다 NSMutableArray를 예로 들겠습니다 NSMutableArray에는 객체를 추가하는 함수가 있습니다 addObject:인데 하나 예를 들죠 NSString *str = @”test”; 일단 문자열 객체를 준비합니다 NSMutableArray *array = [NSMutableArray array]; 더이상 alloc init을 볼일이 없이 바로 오토릴리즈 된 배열 객체를 준비합니다. [array addObject:str]; array 객체에 str을 넣었습니다. 간단히 생각하면 넣었다 라고 보겠지만 실제로 메모리 관리는 어떻게 될까요? NSMutableArray는 객체를 새로 추가 받는 함수가 실행되면 자동으로 그 객체에게 retain 함수를 날립니다. 즉 여기서는 더이상 str을 쓸일이 없더라도 array는 str을 받은 이상 계속 가지고 있어야할 책임이 생긴겁니다. 리테인 카운트를 올려두었기 때문에 현재 코드에서 더이상 안쓴다 해도 객체는 유지됩니다. 하지만 별로 신경쓸 문제는 아닙니다. NSMutableArray클래스는 객체를 받으면 책임 지기때문에 해제또한 책임 집니다. 즉 array가 오토 릴리즈 상태이기때문에 나중에 해제 될때 가지고 있던 모든 객체에게 다 release를 날려주게 됩니다. 근데 넣어둔 객체 메모리 관리를 한답시고 직접 release를 날려버리면 해당 str객체는 해제 되겠지만 array는 객체가 있는줄 알고 쓰레기 주소에 메세지를 때렸다가 베드 엑세스 에러가 나고맙니다. 결국 자기가 받은 객체는 자신이 책임 지는 구조입니다. 그렇다면 클래스에 선언한 전역 변수는 어떻게 될까요? 함수 내부에서 만들어 쓰고 끝나는 것들은 전부 오토릴리즈로 사용하겠지만 전역변수는 다릅니다. 더이상 안쓸때까지 retainCount를 하나 올려둬야 합니다. 그리고  객체가 해제될때 호출되는 dealloc함수에서 해당 전역 변수의 객체들을 다 해제 시켜줍니다. 처음 생성할때 alloc init으로 가지고 있어도 되고, 아니면 다른 함수를 통해 오토릴리즈된 객체를 가지고 있다면 이럴때 retain을 사용하면 됩니다. title = [[NSString alloc] initWithString:@”tes”]; OR title = [[커스텀클래스 getTitle] retain]; 그리고  - (void)dealloc { [title release]; ... 즉 객체가 해제될때 가지고 있던 객체들도 같이 해제 해주는겁니다. 그럼 전역 변수도 알았습니다. 프로퍼티는 무엇일까요? 여기까지 이해했다 하더라도 object.title = ? 식의 코드를 보면 또다시 해맵니다. 1. object.title = [[NSString alloc] initWithString:@”Test”]; 2. object.title = @”Test”; 3. object.title = [NSString stringWithString:@”Test”]; 위의 1,2,3중 어느것이 맞다고 봅니까? 2, 3번이 맞는겁니다. 보통 문자열의 경우 2번이 제일 간단하면 3번과 별차이 없기때문에 2번을 사용합니다. 위와같은 점문법은 보통 프로퍼티(속성)로 정의되어 있는 경우입니다. 프로퍼티는 C++배울때 많이 듣던 setter, getter입니다. 즉 외부에서 해당 객체의 내부 변수에 접근할수 있도록 접근용 함수를 만드는 것입니다. 프로퍼티 선언은 먼저 헤더에서 합니다. 그리고 본문에서 @synthesize 선언을 해주면 정의한 속성이 설정됩니다. 그리고 위 선언을 하면 컴파일러에서 자동으로  - (NSString *)title이라는 getter함수와 - (void)setTitle:(NSString)이라는 setter함수가 자동 생성됩니다. 그리고 프로퍼티 설정에서 주의해야 할 부분이 있습니다. retain이라는 부분인데 이부분이 retain, assign,  그리고 copy일수 있습니다. getter함수는 단순히 그 변수를 돌려주면 되기때문에 특별한 조치는 없고 setter함수가 위 세가지 설정에 따라 내용이 달라집니다. 먼저 retain retain이 설정되어 있으면 기본적으로 setter에서 기존의 title에 뭔가 있을 경우를 대비에 release를 먼저 날려주고 새로운 객체를 retain걸어주면서 받습니다. assign의 경우 리테인 카운트에 아무런 영향 없이 객체의 주소만 지정하게 됩니다. 보통 델리게이트 등 객체의 주소만 지정할때 사용됩니다. 마지막으로 copy 는 retain과 비슷하지만 retain부분 대신 copy가 들어가서 객체를 복사할때 사용됩니다. 객체.title라고 써서 읽어 오는것은 [객체 title]로 써있는것과 같은 역활을 하고 객체.title = ? 식으로 지정하는것은 [객체 setTitle:?]식으로 설정 함수를 호출하는 것과 같습니다. setter의 경우 앞서 다루어 봤던 NSMutableArray에서 addObject와 비슷하죠? 즉 속성으로 호출되는 것들은 다 함수입니다. 변수라고 착각을 하기때문에 위에서 1번과 같은 경우가 생기는 겁니다. 프로퍼티가 retain이나 copy인 경우 dealloc에서 title = nil; [self.title release] 어느쪽이 맞다고 생각합니까? 둘다 틀렸습니다. 1번은 전역인데 release안하고 넘어가서 문제가 되고 2번은 title함수로 불러온 title객체에 release를 때려서 객체는 해제 되었지만 title객체변수는 여전히 주소를 쥐고 있어서 문제가 될 여지가 있습니다 맞는 방법은 [title release];  title = nil; 아니면 self.title = nil; 입니다 후자의 경우 [self setTitle:nil]; 이 실행된 경우인데 위 retain 경우 함수를 보면 먼저 기존에 가지고 있던 객체에는 release를 보냅니다 문제없이 해제되고 그다음 title = [newTitle retain];에서 newTitle이 nil값이기때문에 title = [nil retain];이 됩니다 재미있는 점은  nil에는 무슨 메세지를 날려도 아무런 문제가 없습니다 0 x 어떤 숫자든 = 0인 원리 즉 title = nil이 됩니다 자 그럼 정리해 보겠습니다. 함수내에서 쓰는 객체들은 전부 오토릴리즈(autorelease)로 한다. alloc init 과 release무더기면 코드만 해맨다 전역 변수는 지정할때 리테인카운트를 하나 올린고 안쓸때 해제한다. 계속 가지고 있을것이니 retain, 더이상 안쓸때는 release! 전역 변수에 객체를 사용하다가 해제(release)를 하면 미련없이 nil처리 (변수 = nil;)하자 release하고나면 반드시 변수 = nil; 해서 이후에 실수로 접근해도 문제없다. 프로퍼티는 전역 변수가 아니다! self.title과 title, 헤깔리지 말자. 다른 객체에 전달하는거, 알아서 하겠지. 신경쓰지 말자. NSMutableArray같은 관리 객체에 넣어둔거 해제될때 알아서 내용도 해제 시킨다. retainCount함수로 일일이 확인해보지 말자 괜히 헤깔린다. 상황에 따라 예상보다 더 나오는 경우도 있습니다 그만큼 더 해제 시킨다고 해매지 마세요. 내가 만든 함수도 객체를 돌려줄땐 오토릴리즈로 돌려주자 규칙! 특의한 경우로 NSTimer같은 경우는 오토릴리즈 되어 있어도 타이머가 돌고있는 상태에는 시간이 지나도 해제를 안합니다 타이머가 정지되면 동시에 해제되어 버립니다. 리테인 했었으면 릴리즈 해주고 안했었으면 그냥 nil처리 해주면 무난합니다. 마치며... Objective-C는 이름 그대로 객체 지향에 특화된 언어입니다. 객체간의 서로가 왠만해선 참견 안하는것이 규칙으로 되어 있습니다. 필요한 호출만 서로 해주고 내부는 어떻게 돌아가는지 신경안쓰는 것이죠. 차를 그저 운전할뿐이지 엔진 설계도 까지 읽어보나요? Moon_iPhone_Study, 왠지_졸려서_헛소리_한듯한...  작성자의 카페글 더보기 문씨님의 블로그 덧글 116개 | 등록순 | 조회수 5770 | 추천 4 담기 (+47) | 인쇄 | 신고 천상을달리다 2010/08/07 21:47답글|신고 문씨님 강좌는 매번 잘보고있습니다. ^^ 공사중이신데 완공되길 기다리고있겠습니다. ㅎㅎ 아이맨 2010/08/07 22:46답글|신고 통이론인가요? ㅋㅋ 통째로 관리? 그거로 하시나요? 뭐 여하튼 기대 하겠습니다. 까페 검색하다 보니 문씨님의 실력이 출중하시던데 . . . 랑유 2010/08/07 23:22답글|신고 우와 기대됩니다>ㅂ< 팬더두현 2010/08/07 23:35답글|신고 공사중_공사중_공사중_공사중_공사중_공사중_공사중_공사중_공사중_공사중_공사중_공사중_ㅋㅋㅋ 태그 잼있내요 ㅋㅋ 레버 2010/08/08 00:54답글|신고 으아 메모리 때문에 고생하고 있는데 기대되네요 +_+ 완성될때까지 잠안자고 기다립니다 ㅎㅎ 문씨 2010/08/08 01:33신고 잠 안자고 빨리 쓸게요 -_-;;; 레버 2010/08/08 02:27신고 윽... 피곤하시면 내일하세요 ( -_);;; 문씨 2010/08/08 02:50신고 7장째... 초보아이폰개발 2010/08/08 04:06답글|신고 ㅋㅋㅋ 고생하시네요.ㅠㅠ 기다리고있습니다!!ㅋㅋㅋ힘내세요!! (pc방에서...) 문씨 2010/08/08 04:07신고 ㄷㄷㄷ;;; 11장째 입니다 -_-ㅋ 문씨 2010/08/08 04:39답글|신고 완료.... 잘 쓰다가 나중에 졸면서 쓴 부분도 있을겁니다 -_-;;; 이해 안되는 부분은 알려주세요 레버 2010/08/08 05:14답글|신고 하악 정말 안주무시고 올려주시다니.... 잘보겠습니다.!!!! 애벌레 2010/08/08 11:43답글|신고 좋은 내용 정말 감사드립니다. 애벌레 2010/08/08 11:52답글|신고 클래스 전역 변수(클래스 인스턴스)에 포인터 값을 직접 대입할 경우 어떻게 되는지 궁금한데요.. 예를 들면 @interface Exam : NSObject{ NSObject * test; } 이후 타 클래스에서 @interface Test2 : NSObject{ Exam *exam; NSObject *tett; } 하고 실제 사용할때 tett = [[NSObject alloc] init]; exam = [[Exam alloc] init]; exam = tett; 이런식으로 포인터를 직접 대입 할 경우 어떻게 되는지 궁금합니다. 제 개인적인 생각으로 @property [nonAtomic, retain] NSObject *test; 로 retain 설정 해주면 괜찮다고 생각합니다만.. 문씨 2010/08/08 13:17신고 exam = [[Exam alloc] init]; //생성하고 exam = tett; //다른 객체 주소로 덧씌우는경우 메모리 누수가 됩니다. property로 선언한것은 self.exam = [[[Exam alloc] init] autorelease]; self.exam = tett; 식으로 사용해야 합니다. exam과 self.exam은 다른겁니다. 천상을달리다 2010/08/08 14:08답글|신고 그동안 헷갈렸던 개념중에 하나 질문드립니다. ^^; @interface A : UIViewController { UIImageView* pImageView; } 1번 @property (nonatomic, retain) UIImageView* pImageView; <여기서 리타인카운트 1증가? .m 2번 pImageView = [[UIImageView alloc] initWith.....] < 여기서 리타인카운드 1증가 그렇다면.. 1번의 경우가 리타인카운트증가가 되는거라면 release 를 두번해줘야하는건가요? 저는 보통 dealloc에서 한번만 release하고 넘어가거든요 -ㅁ-; 그동안 좀 이해안된개념중 하나입니다. ^^; 문씨 2010/08/08 19:35신고 전역 변수와 프로퍼티와 그 정의를 해매시는듯합니다. pImageView는 전역 변수이니 지금 하신다는 대로 하시면 되고 self.pImageView 같이 사용되는 경우가 프로퍼티를 사용하는 경우입니다. 전역변수만 사용하는 경우 pImageView = [[UIImageView alloc] initWith.....] dealloc에서 [pImageView release]; pImageView = nil; 프로퍼티로 사용하는 경우 self.pImageView = [[[UIImageView alloc] initWith.....] autorelease]; dealloc에서 self.pImageView = nil; 문씨 2010/08/08 19:36신고 프로퍼티는 그저 외부에서 접근할수 있도록 선언을 해줌으로써 setter와 getter함수가 자동 생성되도록 하는 것일뿐 전역변수와는 관련이 없습니다. 프로퍼티는 함수일 뿐입니다. (그렇게 안보일뿐) 천상을달리다 2010/08/08 20:54신고 아 이제 이해할거같네요. 여태 NSArray나 인터페이스빌더에서 건들수있는 것들은 죄다 프로퍼티선언을 해줬는데 딱히 IBOutlet가 연결된게 아니라면 프로퍼티안해주고 사용해도됐군요 생각해보니 IBOutlet으로 연결해놓는건 프로젝트 내부에서 alloc안해줘도 되니까요 ^^ 명확하게 이해가 되서 그동안 만들었던 소스 싹 수정했네요 ㅎ 감사합니다.!! //아 뒤늦게 생각해보니 제가 바로 위에쓴것도 잘못됐군요 ^^; IBOutlet로 설정해도 프로퍼티안하고 사용할수있으니까요;; 하나만 더 질문드리겠습니다. ^^; 프로퍼티 선언된건 self.객체이름 으로 접근하라고하셨는데 appDelegate에 보면 UIWindow는 프로퍼티선언이 되있는데 self.window로 접근하지않더군요 이건 IBOutlet으로 연결되어있어서 그런건가요? 문씨 2010/08/08 21:49신고 self.window는 [self window]함수로 window객체변수의 주소를 리턴합니다. 결국 내용물은 같은 거죠 ㅇㅇ 2010/08/08 17:00답글|신고 그동안 예제 코드를 보면서 그런가보다 하면서 받아들이고 넘어간 부분에 대해 하나씩 차근차근 잘 설명해주셔서 정말 고맙습니다. 복 많이 받으세요~~ 아직 @property가 하는 역할을 잘 이해하지 못했지만....저는 그냥 헤더 파일의 @interface에서 선언/@property 설정 m파일에서 @synthesize해주는 것이 전역 변수(객체) 사용법이구나 했었는데..좀더 공부가 필요한 것 같습니다.;; 핥핥 2010/08/08 18:12답글|신고 아... 너무 좋은 내용 감사합니다 대에박 2010/08/08 19:45답글|신고 잘봤습니다~~ 아직 다 이해는 못했지만 큰 도움이 됬습니다. ㅎ 꾸띠앙 2010/08/08 22:13답글|신고 정말 좋은강좌입니다. 감사합니다~ TigerKim 2010/08/08 22:13답글|신고 먼저 좋은 강의 감사드립니다. :) 질문이 하나 있어요. 외국에 어떤 블로거가 코딩해놓은 걸 보니까 헤더에 전역변수로는 앞에 '_' 를 붙이고, property 에서는 '_'를 빼고, synthesize 에서는 '_' 붙인 것과 아닌 것을 같다고 정의하더라고요. 아래 코드로 설명하면.. .h :: { NSArray * _example; } @property (nonatomic, retain) NSArray * example; .m :: @synthesize example = _example 이런식으로요. 그리고 밑에 함수에서는 주로 self.example 이렇게 쓰고. 조건문같은데서만 if (_example) 같이 나오고요. 완벽히 이해가 안되다보니 그냥 단순히 개인의 스타일같긴 하지만 이렇게 하는것이 메모리관리에 도움이 되는건가요? 문씨님 강의를 보니 조금 감이 잡힐것 같으면서도 저건 이해가 되질 않네요. 답변 미리 감사드립니다. ^^ 와이씨 2010/08/08 22:48신고 아 이거 저도 궁금했던건데.. 제가 추측한건 전역변수와 프로퍼티 헷갈리지 않고 명확하게 하려고 저렇게 해주는것 같긴 한데.. 다른 이유가 있는건지 궁금하네요~ TigerKim 2010/08/08 22:13답글|신고 아, 그리고 추가로 하나만 더 여쭙자면 여지껏은 주로 dealloc 에서 release 만해주고 nil 처리는 안해주었는데 위에 보니까 다 처리해주시는거 같더라고요. 인스트루먼트같은데서도 특별히 문제가 없었던거 같은데 꼭 필요한건가요? 500자가 넘어서 별도의 리플로 올립니다.; 답변 부탁드릴께요~ 감사합니다. :) 문씨 2010/08/08 22:41신고 2탄에서 정리해 드릴께요 블루크리스탈 2010/08/08 23:31답글|신고 아직 모든걸 이해 하진 못했지만 많이 배웠습니다. 좀 더 공부해야겠네요 정리 감사 합니다. 클린트 2010/08/09 01:10답글|신고 소중한 정리 글 감사합니다. 문씨님 글떳다고 살짝 소문 흘렸습니다. ^^;; 고생하셨습니다.~ 엄청좋아하더라구요~ 웜홀 2010/08/09 09:42답글|신고 아직 이해 못하는 부분도 많지만 좋은글 감사합니다^^ 문씨 2010/08/10 19:47신고 이해가 안가는 부분은 지적해 주세요 퓨리넬 2010/08/09 10:05답글|신고 역시 문씨님 대단하십니다. 정말 감사합니다. ^^ 수빈아빠 2010/08/09 10:12답글|신고 오웃 감사~ tOriDas 2010/08/09 10:35답글|신고 좋은 글 감사합니다~ 후이 2010/08/09 10:38답글|신고 정말 감사합니다~ 초보아이폰개발 2010/08/09 10:55답글|신고 ㅎㅎ 좋은글 감사드립니다!!히.ㅋ 감사히 보겟습니다~ 시리 2010/08/09 11:16답글|신고 좋은글 감사드립니다. 아르모니 2010/08/09 13:39답글|신고 글 잘 봤습니다. 그런데 저는 autorelease는 잘 안 쓰려고 했는데.. 이 글을 보니까 약간 고민되네요. 아무튼 감사합니다. 문씨 2010/08/09 14:53신고 지원 함수들을 사용하면 자연히 오토릴리즈를 사용하게됩니다 레드래빗 2010/08/09 16:13답글|신고 정말감사합니다~ neoskb 2010/08/09 18:24답글|신고 주옥같은 강의 감사드립니다. 다른 언어를 사용하다가 Objective-C를 접하고선 제일 이해하기 힘든 부분이 이 부분이 아닐까 싶습니다. 책을 여러권 보아도 쉽사리 이해되는 게 아니더군요. autorelease를 사용했을 때 release 되는 시점을 명확히 몰라서 가급적 autorelease를 가급적 안쓰려고 하였는데, 문씨님의 글을 읽어보니 명확한 구분이 되는 거 같습니다. 거듭 감사드립니다^^ rokakjy 2010/08/10 09:26답글|신고 감사감사~ 감사합니다^^ 키티호크 2010/08/10 13:53답글|신고 문씨님 강좌는 언제 봐도 일품이네요. 특히 어려웠던 메모리 관리 부분을 잘 정리해주셔서 너무 감사드립니다. proflee 2010/08/10 17:22답글|신고 좋은 글 감사합니다! lpoint2 2010/08/10 19:33답글|신고 약 10%만 이해가 갑니다. 이해가 안되네요.. 문씨 2010/08/10 19:46신고 어떤부분이 어떻게 이해가 안가나요? lpoint2 2010/08/10 20:10답글|신고 1. 함수내에서 쓰는 객체들은 전부 오토릴리즈(autorelease)로 한다. a. autorelease를 하면 메모리가 한없이 증가하지는 않나요? b. 아무리 많이 사용하더라도 문제는 없나요? 2. 전역 변수는 지정할때 리테인카운트를 하나 올린고 안쓸때 해제한다. retain를 2번하면 두번 release를 하나요? 문씨 2010/08/10 20:29신고 1. 아뇨 이벤트루프로 돌아갈때 수시로 비워주기 때문에 증가하지않습니다. 2. retain두번 올리면 당연히 두번 내립니다(release) lpoint2 2010/08/10 20:10답글|신고 1. 전역 변수에 객체를 사용하다가 해제(release)를 하면 미련없이 nil처리 (변수 = nil;)하자 a. 어떨때 self.변수를 사용하고 어떨때 그냥 변수를 사용하나요? 2. 프로퍼티는 전역 변수가 아니다! a. self.title과 title, 헤깔리지 말자. ----------- 헤깔립니다. 문씨 2010/08/10 20:30신고 1. self.변수는 변수가 아니라 프로퍼티입니다.메모리 관리 2편을 읽어주세요. 2. 설명이 부족한거 같아서 2편에서 다시 정리했습니다. lpoint2 2010/08/10 20:10답글|신고 3. 다른 객체에 전달하는거, 알아서 하겠지. 신경쓰지 말자. a. NSMutableArray같은 관리 객체에 넣어둔거 해제될때 알아서 내용도 해제 시킨다. ⁃ alloc를 해도 release를 안해도 되나요? 문씨 2010/08/10 20:32신고 3. 아니요 release해줘야 합니다. 3번의 뜻은 다른 객체에게 전달한 객체까지는 신경쓸 필요가 없다는 겁니다. NSMutableArray객체 해제하면 안에 들어가있는 객체들까지 알아서 해제됩니다. 알아서 해제되기때문에 직접 관리할 필요 없다는 겁니다. lpoint2 2010/08/10 20:11답글|신고 4. retainCount함수로 일일이 확인해보지 말자 괜히 헤깔린다. a. 봐도 헤매고 안봐도 헤맵니다.(실력이 높아지면 틀려질꺼라 생각합니다.) 5. 내가 만든 함수도 객체를 돌려줄땐 오토릴리즈로 돌려주자 1. 내가 만든 함수도 객체를 돌려준다는 말이 이해가 안됩니다. 그래서 오토 릴리즈를 하라는 말도 이해가 안됩니다. 문씨 2010/08/10 20:33신고 4. 보면 더 해매죠 . 이따끔식 의도하지 않는 수치가 뜨기도 합니다. lpoint2 2010/08/10 20:18답글|신고 제가 실력이 없어서 잘 모른다고 생각합니다.(문씨님의 강좌 정말 고맙게 보고 있습니다.) 비주얼 베이직을 하다 객체 프로그램을 보니 이해가 안되는게 많구 특히 retain, copy 등이 이해가 안됩니다. 객체를 만들어서 그냥 사용하면 되는 것을 왜 복잡하게 만드나요? 재사용을 하면 변수를 하나 더 생성해서 내용을 copy를 하더라도 메모리 사용은 같지 않나요? 실력이 없는 제가 느끼기에는 괜히 어렵게 꼬아 놨다는 느낌입니다. 변수를 만들었으면 그 이름으로 사용해야지 왜 앞에 self를 붙여서 머리 아프게 하나요? 내 클래스에서 사용한다면 차라리 속성값을 만들어 private속성을 주는 게 더 나을텐데요. (전역변수와 지역변수를 구분하는게 더 명확하지 않을까요?) self를 붙여야 한다면 언제 붙여야 하고 사용할때 방법이 어떻게 다른가요? lpoint2 2010/08/10 20:19답글|신고 음 초보라서 머리만 너무 아파옵니다. 명확하게 알려면 어떻게 해야 할까요? 위에 설명만으로는 머리 아픈게 해결되지 않아서 모르겠다고 했습니다. 다시 한번 말씀드리지만 문씨님의 강좌 감사합니다. 너무 많이 도움되고 있습니다. 혹시 제가 도움될 만한 내용이 있으면 답변을 달아주세요. 메모리 넘 힘들어요. 문씨 2010/08/10 20:36신고 고민하시는 부분이 아무래도 포인터 개념 같군요. 저도 비베 출신이라 한동안 해맸습니다. 처음 배운 언어가 비베고 그 이후에 해봤던 언어가 PHP였습니다. 결국 메모리 관리랑 전혀 관련없는 언어들만 했었죠... 랑유 2010/08/11 00:32답글|신고 문씨님 정말 감사합니다>ㅂ 부디 강의 모아서 책 출판 꼭 해주세요^^
자수
2010/08/11 01:28답글|신고
먼저 유익한 강좌 잘 보고 있습니다.
저는 왠지 제가 원초적인 내용에 대한 이해가 부족한 것 같아서 그 부분에 대한 질문 두 가지 하겠습니다. retain과 release는 대충 현재 객체 안에서 사용한다, 안한다의 의사표현이라는 정도는 이해할 것 같습니다. 그런데 객체를 변수에 할당(메모리 주소를 할당)하는 것이 retain과 release에 어떤 영향을 주고 있는지 궁금합니다.

예를 들면
aStr = [[NSString alloc] initWithString:@”Test”];
A라는 객체에 위와 같은 aStr이라는 전역변수가 프로퍼티로 선언되어 있을 때 B라는 객체에 있는 전역 변수(역시 프로퍼티선언) b.bStr = a.aStr; 이라고 사용했다면 retain과 release의 관계는 어떻게 되나요? retain 카운트가 증감하는 것은 객체간의 관계에서만 필요한 것인지 아니면 하나의 객체 안에서도 retain을 증가시켜야 하는 상황이 있는 것인지 명확히 개념이 잡히질 않네요.
문씨
2010/08/11 01:38신고
2편에 프로퍼티 편을 보셨는지는 모르겠네요
일단 양쪽다 프로퍼티인 경우를 보자면
b.bStr = a.aStr; 이라고 할경우 풀어보면
b.bStr = [a aStr]; 이 되고
[b setBStr:[a aStr]]; 이됩니다.
결국 b.bStr에 전에 들어가 있던 객체는 해제되고 a.aStr객체를 새로 받으면서 리테인이 올라가죠
메모리 상으로는 문제 없습니다.

단 aStr = [[NSString alloc] initWithString:@”Test”]; 이상태에서
bStr = aStr;
[aStr release];
[bStr release];
하면 문제가 되죠 주소만 복사받았기 때문에 리테인 카운트에 문제가 되는겁나디.
자수
2010/08/11 01:51신고
그렇다면 b.bStr = a.aStr을 하더라도 a.aStr이 참조하고 있는 객체는 참조가 유지되는 것이겠군요 retain 카운트가 증가하는 것은 객체를 참조하는 주소가 복사된다는 개념으로 이해하면 될 것 같군요. 감사합니다.
자수
2010/08/11 01:29답글|신고
두 번째 질문은 UIViewController의 경우에는 기본 만들어지는 함수에 -(void) viewDidUnload와 -(void) dealloc이 있습니다. 그리고 UIView에는 dealloc만 있는데요 UIViewController에서도 dealloc에 그냥 self.method = nil;을 해주고 viewDidUnload에는 작성하지 않아도 되는 것인가요? viewDidUnload가 왜 필요한지, 그리고 viewDidUnload와 dealloc이 언제 실행되는지, 궁금합니다.
문씨
2010/08/11 01:43신고
질문하신 부분은 메모리 관리보다는 UIKit의 UIViewController의 구조와 관련이 있습니다.
UIViewController는 상황에 따라 속성인 view를 지우기도 합니다. 처음 view가 생성되면 viewDidLoad가 호출되기 때문에 그때 화면 구성할 뷰들을 생성해서 넣어주면 되고
뷰가 제거되면 viewDidUnload가 호출되기 때문에 다른 객체들도 해제해줘야 합니다.
데이터 같은 경우는 그냥 유지해도 괜찬지만 뷰에 관련된건 메모리 관리 차원에서 비워주는것이 좋겠죠.
어떤의미에서는 viewDidUnload와 dealloc이 같은 역활을 하는것처럼 보이기도 합니다.
그러니 전역 변수의 경우 release만 하지 말고 release후 nil처리를 하는걸 권장하는겁니다.
viewDidUnload에서 release만 해두면 dealloc에서 다시 release할때 문제가 발생하겠죠.
자수
2010/08/11 01:59신고
그렇군요 nil에 release를 보내도 에러가 나지 않는다는 것이 이해하는데 중요할 것 같네요. 말씀대로라면 viewDidUnload보다 무조건 dealloc이 후에 실행이 되는 것 같네요 도움이 많이 되었습니다. 감사합니다.
울리
2010/08/11 10:12답글|신고
pool 개념인데, autorelease 는 좋네요. objc는 생각보다 개발자를 많이 생각해 주는듯 한 느낌을 받네요.
세이지
2010/08/11 10:37답글|신고
정말 좋은 강좌 감사합니다. ^^ 살며시 담아갈게요~
rokakjy
2010/08/11 13:15답글|신고
좋은정보 감사합니다~~
조은
2010/08/11 15:29답글|신고
글 내용의 예문들이 딱 한눈에 들어와 이해하기 쉬워요. 게다가 프로퍼티개념까지~
질문란의 충실한 답변들을 보고 문씨님 강좌 기대하고있었는데 정말감사합니다^^
(근데 저는 정작 코딩할땐 문제없으면 귀차니즘에 잘 신경도 안쓰게되는.. ㅎㅎ;)
문씨
2010/08/11 15:37신고
iOS 4.0부터는 멀티테스팅 덕분에 메모리 여유가 전에 비해 많이 줄었습니다.
대충 하다간 튕기는 일이 대부분 일겁니다....
이제는 신경 써야 할때-_-a
안드레
2010/08/11 17:25답글|신고
메모리 관리때문에 고생중이였는데 좋은 정보 감사드립니다~^^
KKMF
2010/08/12 15:15답글|신고
문씨님 강좌 너무 좋네요.... 감사합니다.
happydong
2010/08/12 16:47답글|신고
좋은 정보 잘봤습니다~^^
조심히 담아갈게요~~
Tesla
2010/08/13 10:15답글|신고
항상 많은 도움 받고 있습니다..

너무 도움을 받아서 언제 쏘주라도 한잔 사드려야 할것 같습니다...^^
타임맨
2010/08/13 14:51답글|신고
덕분에 시행착오를 줄이겠네요. 감사합니다.
BestSuit
2010/08/13 15:13답글|신고
최고 이십니다!!!!
WishMast
2010/08/13 21:07답글|신고
좋은정보 감사합니다~ ^^
백과사전
2010/08/13 22:09답글|신고
정말 너무 좋은 강좌입니다 정말 ㅎㅎ 기분이 너무 안좋았는데 좋은 강좌를 보고 기분이 다 좋아졌습니다
남가일몽
2010/08/15 14:03답글|신고
감사합니다.^^
군감자
2010/08/15 14:51답글|신고
이렇게 좋은글이 넘 감사합니다.
시나
2010/08/16 16:01답글|신고
속시원한 내용이네요. 감사합니다.
작은예배자
2010/08/16 17:55답글|신고
무작정 책만 보면서 공부를 하다가 몰라서 넘어가는 경우가 많았는데 궁금했더 개념들을 알게 되니깐
머리속이 환해지는듯한 느낌입니다. 정말 오랜만에 깊이 정독했습니다.
문씨님 강의 정말 감사합니다.
다브엘
2010/08/18 10:42답글|신고
좋은 글 감사합니다.
seed
2010/08/18 16:47답글|신고
좋은 글 감사합니다.
제 티스토리에 퍼가요...^^
흐르는강물에
2010/08/19 15:35답글|신고
좋은글 감사합니다
지돌스타
2010/08/20 00:50답글|신고
좋은 강좌 감사합니다.

항상 헷갈렸던게.... Java같은 언어를 사용하다가 Objective-c로 넘어오면서 전역변수를 클래스 내부에서만 사용해야하는 경우 @property나 @synthesize와 같은 지시자를 전혀 사용하지 못하겠더군요. 왜냐하면 @property로 만든이상 외부에서 접근을 허용하게 되는 것이니깐요.

그래서 @interface에 @private MyClass *_myInstance; 전역변수를 정의했다고 했을때

결국 dealloc에서는
[_myInstance release];
_myInstance=nil;

을 해주고

Lazy Creation을 해주어야 하기 때문에
-(MyClass*)myInstance {
if(_myInstance==nil) _myInstance = [[MyClass alloc]init];
return _myInstance;
}

이런식으로 하고 혹시 메모리 문제가 발생할 수 있으므로
applicationDidReceivedMemoryWarning: 함수를 재정의 하여
if( NO == _myInstance.isUse ) {
[_myInstance release];
_myInstance = nil;
}

처럼 만들어서 하는데 제가 메모리 관리를 잘 하고 있는건지요? ^^;

메모리는 차라리 C라면 훨씬 편하겠어요 ㅎㅎㅎ
문씨
2010/08/20 04:49신고
틀린 부분은 없어보이지만 lazy creation이라....
제 경험상 왠만한 객체는 그래픽 출력에 관련된 객체가 아니면 메모리 경고때 비워줄 필요가 없습니다.
작아서요...
디비데이타 객체처럼 용량 많이 먹지만 않는다면 지워줘도 별 차이 없습니다.
다만 화면에 관련된 뷰 객체가 많이 먹죠
지돌스타
2010/08/20 09:02신고
문씨님 답변 주셔서 감사합니다. 언급은 안했지만 예제를 드린 것은 UIView관련 객체와 같은 메모리의 크기가 큰 객체만을 암시적으로 감안하고 있었습니다. 너무 좋은 글 저같은 초보자에게 큰 도움이 되고 있습니다. 언젠가는 저도 문씨님처럼 여기에 도움이 되는 사람이 되도록 노력할께요 ^^
yunchiri
2010/08/20 09:57답글|신고
감사합니다

2010/08/20 14:18답글|신고
이해가 쉬운 강좌내요.. 감사합니다.
가람
2010/08/23 15:12답글|신고
궁금 하게 있는데요

NSString *getMemo = @"-";
이것과
NSString *getMemo = [[NSString alloc] initWithString:@"-"]
이것의 차이가 뭔지

프로그램상에는 오류는 없는데 메모리상에는 차이가 있는지 궁금해서요

2010/08/24 14:49신고
강좌를 읽고 제가 이해한 건

NSString *getMemo = @"-"; 이걸 풀어쓰면
NSString *getMemo = [NSString string]; <- 또는 NSString *getMemo = [[[NSString alloc]init]autorelease];
getMemo = @"-";
즉, 오토릴리즈 되는 놈이고,

NSString *getMemo = [[NSString alloc] initWithString:@"-"]
요놈은 오토릴리즈가 아니라서 release를 개발자가 직접 날려줘야 된다는 것 같네요.

제가 틀린 거면, 알려주세요. ^^;
아이작
2010/08/24 20:47답글|신고
감사합니다 잘읽었습니다.
티나르
2010/08/25 18:14답글|신고
좋은 내용 감사합니다.
한가지 클래스 멤버변수를 전역변수라고 하셔서 좀 헷갈렸네요.
문씨
2010/08/26 17:42신고
아 이런...
용어 정리좀 해야겠네요 -_-;;;;
우레레
2010/08/28 18:32답글|신고
이 강좌 추천입니다.

제가 요즘 Cocos2D로 말풍선 기능 구현하는 데, 어디서 문제가 생기는 건지 알수가 없어서 아주 힘들었거든요. 크래쉬로그 뒤적여서 문제가 뭔지는 알겠는데 어찌 해결해야 할지 ㅠ_ㅠ 아우.... 헌데, self.property = nil; 이걸로 해결. [??? release];는 장렬하게 크래쉬가 발생하네요.

이런 경우도 있군요. 제가 읽어 본 아이폰 관련 서적에서는 이런 내용 못봤는데. 정말 감사합니다.
Kisin 입
2010/08/30 20:17답글|신고
문씨님 정말 이렇게 좋은 강의 감사드립니다.
하루살이
2010/08/31 19:49답글|신고
잘 읽었어요..명쾌하게 설명 잘해주셔서 감사합니다.
코드라이더
2010/09/01 16:40답글|신고
좋은 자료 감사해요
freshful
2010/09/01 18:44답글|신고
너무너무 감사합니다. 정말 완전 감동했습니다.
12

댓글 없음:

댓글 쓰기