클래스와오브젝트 메모리관리 순천향대학교컴퓨터공학과이상정 1 Objective-C 소개 C 언어에 Smalltalk 스타일의메시지전달을결합한객체지향프로그래밍언어 Objective-C 와코코아는 Mac OS X 운영체제의핵심 개발역사 1980 년대초에 Stepstone 사의 Brad Cox 와 Tom Love 가개발 1985년에 Steve Jobs가저렴한워크스테이션개발을위해 NeXT 사설립 UNIX에Objective-C로작성된인터페이스툴킷의NextSTEP 운영체제개발 1996년애플이 NeXT 사인수하고 Mac OS X 운영체제발표 순천향대학교컴퓨터공학과이상정 2
클래스와오브젝트 순천향대학교컴퓨터공학과이상정 3 클래스 Objective-C 클래스는일반객체지향언어의클래스와동일 클래스는상태 ( 인스턴스변수, 프로퍼티 ) 와동작 ( 메서드 ) 로구성 프로그램은오브젝트간메시지송수신으로동작 Objective-C 컴파일러지시어는 @ 로시작 클래스구성 @interface 와 @implementation 으로구분 @interface 는인스턴스변수와메서드를선언하며헤더파일에저장 @implementation ti 은메서드를구현하며소스파일에저장 파일구성.h 는헤더파일을표시 클래스, 타입, 함수, 상수등을포함.m은 C 언어확장소스파일을표시.mm 은 C++ 언어확장소스파일표시 순천향대학교컴퓨터공학과이상정 4
클래스선언및구현구조예 NSObject 을상속받는 Simple 클래스예 #import 지시어는 C 언어의 #include 와유사 같은헤더파일여러번포함해도한번만포함 // Simple.h // Simple.mm #import <Foundation/Foundation.h> @interface Simple : NSObject { // 인스턴스변수선언 // 메서드선언 @end #import "Simple.h" @implementation Simple // 메서드정의 @end 순천향대학교컴퓨터공학과이상정 5 메서드선언과구현 @interface 에서메서드선언예 - (void) sayhello: (NSString *) name; 인수 name 과리턴값이없는 (void) sayhello 메서드선언 C/C++ 의 void sayhello(nsstring *name); @implementation에서메서드구현예 - (void) sayhello: (NSString *) name { NSMutableString *message = [[NSMutableString alloc] initwithstring:@"hello there"]; [message appendstring:name]; NSLog(message); [message release]; 순천향대학교컴퓨터공학과이상정 6
메서드구현설명 코코아에서문자열처리는 NSString 클래스사용 문자열상수앞에 @ 표시 NSString 은문자열내용변경이불가능 (immutable) NSString 의서브클래스 NSMutableString 클래스를사용하면문자열변경이가능 (mutable) NSMutableString *message = [[NSMutableString alloc] initwithstring:@"hello there"]; 클래스인스턴스생성 ( 동적할당 ) 시 alloc 메서드사용 C++ 표현 NSMutableString *messgae = new NSMutableString("Hello there "); [message appendstring:name]; 메시지의시작과종료는 [] C++ 표현 message->appendstring(name); NSLog() 함수는콘솔에출력하는함수 [message release]; 메모리해제, C++: delete message; 순천향대학교컴퓨터공학과이상정 7 Simple 클래스예제 1 (1) Simple 클래스구현하여콘솔에 hello 메시지출력하는예 1. View-based Application 을생성하고프로젝트이름을 SimpleClass로지정 2. Groups & Files 목록에서 Classes 를마우스오른쪽버튼으로클릭하고 [Add]-[New Group] 을선택한다. 그룹이름은 Objective-C로지정 3. Objective-C 폴더를마우스오른쪽버튼으로클릭하고 [Add]-[New File] 을선택한다. New File 창에서 Cocoa Touch Class 템플릿을선택한후Objective-C 클래스를선택한다. 그리고 Subclass는 NSObject를선택한후 Next를클릭 순천향대학교컴퓨터공학과이상정 8
Simple 클래스예제 1 (2) 4. 다음화면에서클래스이름을 Simple 로지정하고헤더파일생성체크박스체크하면 Simple.h, Simple.m 파일자동생성 5. Simple.h, Simple.m 파일을열고 sayhello 메서드가추가되도록소스를수정 // Simple.h #import <Foundation/Foundation.h> @interface Simple : NSObject { - (void) sayhello: (NSString *) name; @end 순천향대학교컴퓨터공학과이상정 9 Simple 클래스예제 1 (3) // Simple.m #import "Simple.h" @implementation Simple - (void) sayhello: (NSString *) name { NSMutableString *message = [[NSMutableString alloc] initwithstring:@"hello there"]; [message appendstring:name]; name]; NSLog(message); [message release]; @end 순천향대학교컴퓨터공학과이상정 10
Simple 클래스예제 1(4) 6. main.mm 파일을열고 Simple.h 를 import 하고, Simple 인스턴스를만들어서 sayhello 메서드를호출한다. // main.m #import <UIKit/UIKit.h> #import "Simple.h" int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Simple * mysimple = [[Simple alloc] init]; [mysimple sayhello:@"lee"]; [mysimple release]; int retval = UIApplicationMain(argc, argv, nil, nil); [pool release]; return retval; 순천향대학교컴퓨터공학과이상정 11 Simple 클래스예제 1 (5) 7. 빌드하고실행하여디버거콘솔창에 hello 메시지가출력되는것을확인 순천향대학교컴퓨터공학과이상정 12
Public, Private, Protected 인스턴스변수 클래스내의멤버접근자 @private 인스턴스변수를선언한클래스안에서만사용 ( 접근 ) 가능 @protected 인스턴스변수를선언한클래스와이를상속받은자식클래스에서사용가능 @public 모든클래스에서사용가능 @public NSString *groupname; int intgroupsize @private NSString *othergroupname; int intothergroupsize; 순천향대학교컴퓨터공학과이상정 13 메시지전송 (1) Objective-C 에서는메서드호출을 수신자에게메시지를전송 한다고함 메시지는 [ 로시작하여 ]; 로끝남 [ 뒤에는오브젝트와메시지 ( 메서드 ) 가오며, 다음에 : 와함께인수들을표시 [objinstancesimple sayhello: @"Lee"]; 오브젝트메서드인수 위예의 C++/Java 표현 objinstancesimple.sayhello("lee") 여러개인수표현은다음장에서소개 순천향대학교컴퓨터공학과이상정 14
메시지전송 (2) 중첩된메시지를사용하여인수전달예 [objmyobject getfoo: [objmyfooidentifier getid]]; C++/Java 표현 objmyobject.getfoo(objmyfooidentifier.getid()); self 키워드 자기자신의오브젝트를가리킴 C++ 의 this 에해당 자기자신의오브젝트에메시지를전송 - (void) gohome { [self pickupmilk]; - (Milk *) pickupmilk { 순천향대학교컴퓨터공학과이상정 15 인스턴스메서드와클래스메서드 인스턴스메서드 (instance method) 클래스의인스턴스를미리생성해야하는메서드 - 로시작 클래스메서드 (class method) 클래스의인스턴스가필요없는메서드 + 로시작 C++/Java 의 static ti 메서드와유사 오브젝트인스턴스를할당하는클래스의 alloc 메서드가클래스메서드의예 부모클래스에서 alloc 메서드를탐색 순천향대학교컴퓨터공학과이상정 16
Simple 클래스예제 2(1) 앞의 Simple 클래스예제 1 에 saygoodbye 클래스메서드를추가한예 1. 앞예제의 SimpleCalss 프로젝트에서 Simple.h 파일을오픈하여 saygoodbye y 메서드선언 // Simple.h #import <Foundation/Foundation.h> @interface Simple : NSObject { + (void) saygoodbye; - (void) sayhello: (NSString *) name; @end 순천향대학교컴퓨터공학과이상정 17 Simple 클래스예제 2(2) 2. Simple.mm 에 saygoodbye 메서드구현추가 // Simple.m #import "Simple.h" @implementation Simple + (void) saygoodbye { NSLog(@"Goodbye "); - (void) sayhello: (NSString *) name{ NSMutableString *message = [[NSMutableString alloc] initwithstring:@"hello there"]; [message appendstring:name]; NSLog(message); [message release]; @end 순천향대학교컴퓨터공학과이상정 18
Simple 클래스예제 2(2) 3. main.mm 에 saygoodbye 메서드호출추가 // main.m #import <UIKit/UIKit.h> #import "Simple.h" int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Simple * mysimple = [[Simple alloc] init]; [mysimple sayhello:@"lee"]; [mysimple release]; [Simple saygoodbye]; int retval = UIApplicationMain(argc, argv, nil, nil); [pool release]; return retval; 순천향대학교컴퓨터공학과이상정 19 Simple 클래스예제 2(3) 3. 빌드하고실행하여디버거콘솔창에 Goodbye 메시지가출력되는것을확인 순천향대학교컴퓨터공학과이상정 20
메모리관리 순천향대학교컴퓨터공학과이상정 21 메모리관리개요 아이폰 Objective-C 프로그래밍에서는메모리할당하고사용후에반드시해제해야함 메모리를해제하지않으면메모리누수 (memory leakage) 가발생하여나중에메모리부족으로프로그램실행멈춤 메모리를해제하여반환후에는이를참조하지않도록주의해야하며사용하는경우에러발생 아이폰에서는메모리를자동으로해제하고주기적으로관리해주는가비지컬렉션 (garbage collection) 기능제공하지 않음 사용자가프로그램작성시사용하지않는메모리는반드시해제해야함 메모리할당및참조에관련해서는 alloc, retain, copy 메서드사용 해제시에는 release 메서드사용 순천향대학교컴퓨터공학과이상정 22
메모리관리관련 NSObject 메서드 메모리관련메서드 +alloc -autorelease -dealloc -release -retain -copy 설명새로운오브젝트의메모리를할당하고참조횟수를 1로지정오토릴리즈풀에오브젝트를추가참조횟수가 0이되면호출되어오브젝트의메모리를해제반환오브젝트의참조횟수를 1 감소오브젝트의참조횟수를 1 증가시키고오브젝트의 id 반환오브젝트의복사본을만들고참조횟수는 1로지정 순천향대학교컴퓨터공학과이상정 23 alloc, init 메서드 alloc 메서드 메모리공간을할당받아클래스의인스턴스를생성하는메서드 부모클래스인 NSObject 클래스에서상속받아사용 init 메서드 alloc 을생성된인스턴스를초기화하는메서드 부모클래스인 NSObject 클래스에서정의 생성된인스턴스에서직접초기화시에는 init it 메서드를오버라이드 (override) init 메서드오버라이딩시에는항상부모의 init 메서드호출해야함 오브젝트의인스턴스를가리키는포인터인 id 데이터타입을반환 순천향대학교컴퓨터공학과이상정 24
init 메서드예 간단한 init 메서드예 - (id) init { if (self = [super init]) magicnumber = 5; return self; 부모 init 메서드호출하여부모 id를리턴 부모 init 메서드에서에러발생시에는 nil을리턴하여 false가됨 정수인수를갖는 init 메서드예 - (id) initwithint : (int) value { if (self = [super init]) it]) magicnumber = value; return self; 순천향대학교컴퓨터공학과이상정 25 참조횟수 참조횟수 (reference count) 모든오브젝트는메모리사용여부를판단하는참조횟수의정수값을지정 retaincount 메시지로참조횟수값표시 오브젝트의메모리할당 (alloc, copy 메서드 ) 시 1 로초기화 오브젝트의새로운참조 (retain 메서드 ) 시에는 1 증가 오브젝트의참조종료 (release 메서드 ) 시1 감소 오브젝트의참조횟수가 0 이되면자동으로부모클래스 (NSObject) 의 dealloc 메서드를호출하여메모리를해제하고반환 Simple *objsimple = [[Simple alloc] init]; // 참조횟수 1 [objsimple sayhello: @"Lee"]; [objsimple release]; // 참조횟수 0이되어 dealloc 호출 순천향대학교컴퓨터공학과이상정 26
retain 예 (1) Simple *objsimple = [[Simple alloc] init]; // 참조횟수 1 Simple *objsimpletwo = objsimple; NSLog(@"retaincount: %d", [objsimple retaincount]); // 참조횟수 1 출력 [objsimple sayhello: @"Lee"]; [objsimple release]; // 참조횟수 0이되어 dealloc 호출하여메모리해제반환 [objsimpletwo sayhello: @"Park"]; //!! 오브젝트가이미해제되어에러발생 순천향대학교컴퓨터공학과이상정 27 retain 예 (2) Simple *objsimple = [[Simple alloc] init]; // 참조횟수 1 Simple *objsimpletwo = objsimple; [objsimpletwo retain]; // 참조횟수증가하여 2 NSLog(@"retaincount: t: %d", [objsimple retaincount]); t]); // 참조횟수 2 출력 [objsimple sayhello: @Lee]; @"Lee"]; [objsimple release]; // 참조횟수감소되어 1 // 참조획수 0이아니므로 dealloc 호출하지않음 [objsimpletwo sayhello: @"Park"]; 순천향대학교컴퓨터공학과이상정 28
Simple 클래스예제 3(1) 앞의 Simple 클래스예제 2 에 alloc, retain, release, dealloc 메서드를구현추가한예 오버라이드하여구현하고, 부모클래스의 super 메서드호출 1. 앞예제의 SimpleCalss 프로젝트에서 Simple.m 파일을오픈하여메모리관리메서드추가 // Simple.mm #import "Simple.h" @implementation Simple + (void) saygoodbye { NSLog(@"Goodbye "); 순천향대학교컴퓨터공학과이상정 29 아이폰 - (void) 프로그래밍 sayhello: (NSString *) name { NSMutableString *message = [[NSMutableString alloc] initwithstring:@"hello there"]; [message appendstring:name]; NSLog(message); [message release]; - (id) alloc { NSLog(@"allocating Simple "); return [super alloc]; - (id) retain { NSLog(@"retaining Simple "); return [super retain]; -(id) release{ NSLog(@"releasing Simple "); return [super release]; -(id) dealloc{ NSLog(@"deallocating Simple "); return [super dealloc]; 순천향대학교컴퓨터공학과이상정 30 @end
Simple 클래스예제 3(2) 2. main.mm 에서참조횟수값표시하도록수정 // main.m #import <UIKit/UIKit.h> #import "Simple.h" int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Simple * mysimple = [[Simple alloc] init]; NSLog(@"retainCount: %d", [mysimple retaincount]); [mysimple sayhello:@"lee"]; [mysimple release]; [Simple saygoodbye]; int retval = UIApplicationMain(argc, argv, nil, nil); [pool release]; return retval; 순천향대학교컴퓨터공학과이상정 31 Simple 클래스예제 3(3) 3. 빌드하고실행하여디버거콘솔창에메시지가출력되는것을확인 순천향대학교컴퓨터공학과이상정 32
인스턴스변수와메모리 (1) 인스턴스변수의메모리관리예 인스턴스변수 personname 예 #import <Foundation/Foundation.h> @interface Simple : NSObject { NSString *personname; + (void) saygoodbye; - (void) sayhello: (NSString *) name; @end 순천향대학교컴퓨터공학과이상정 33 인스턴스변수와메모리 (2) 인스턴스변수 personname 대입예 - (void) sayhello: (NSString *) name { NSMutableString St *message = [[NSMutableString St alloc] initwithstring:@"hello there"]; [message appendstring:name]; NSLog(message); personname = [name retain]; [message release]; 인스턴스변수에오브젝트를대입하는경우에는 retain 메시지로참조횟수를증가시켜서메모리해제를방지 다음장에서더나은해결책으로프로퍼티를소개 순천향대학교컴퓨터공학과이상정 34
오토릴리즈풀 오토릴리즈풀 (autorelease pool) 오브젝트의참조횟수를자동으로관리하는풀 NSAutoreleasePool 릴리즈풀을생성후관리 autorelease 메서드로릴리즈풀에오브젝트를등록 릴리즈풀이해제 (release) 될때풀에등록된모든오브젝트가해제 (release) NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; Simple *objsimple = [[[Simple alloc] autorelease] init]; [objsimple sayhello:@"kim"]; [pool release] 순천향대학교컴퓨터공학과이상정 35