아이폰 개발할때, 유저 정의하는 클래스 생성하는 방법

1. 유저 정의 클래스 생성하기
2. 오브젝트의 생명주기
3. Autorelease
4. Objective-C 속성(Properties)

1. 유저 정의 클래스 생성하기

클래스 디자인 하기

클래스 명을 정하고 슈퍼클래스를 정한다. 필요한 속성과 액션을 정의한다.


메소드(Methods), 셀렉터(Selectors), 메세지(Messages)의 차이와 복습

메소드는 오브젝트의 액션을 정의한 것이다.
- (NSString *)name
{
// 구현
}
- (void)setName:(NSString *)name
{
// 구현
}

셀렉터는 메소드를 참조하기 위한 이름이다. 콜론을 포함하지만 실제 파라메터나 타입은 포함하지 않는다.
SEL mySelector = @selector(name);
SEL anotherSelector = @selector(setName:);
SEL lastSelector = @selector(doStuff:withThing:andThing:);


메세지는 오브젝트의 셀렉터를 실행시키기 위한 방법이다. 필요에 따라 파라메터도 같이 적는다.
NSString *name = [myPerson name];
[myPerson setName:@“New Name”];


클래스 정의
(Public 헤더와 Private implementation)

.h 가 헤더이고 .m 이 소스 파일 이란것은 지금까지 해온 것이기 때문에 구지 다시 설명하지 않아도 될 것이다.

여기서 다시 한번 짚고 넘어 갈 부분은 자기 클래스의 메소드를 호출할때는 self를 사용하고,

슈퍼 클래스의 메소드를 호출할 때는 super를 사용한다는 것이다. self는 자바와 비교하면 자바의 this와 같은 개념이다.


<예>
[self doSomething]
[super doSomething]

2. 오브젝트의 생명주기(Object Lifecycle)

오브젝트의 생성에는 allocinit의 두 단계를 거친다. new는 alloc/init을 대신할수 있지만 별로 쓰이지 않는다.
왜냐하면 실 프로젝트에서는 init 대신 initWith라는 초기값을 가지는 (유저정의)초기화 메소드를 사용하는 경우가 더 많기 때문이다.

#import "Person.h"

@implementation Person
- (id)init {
    // allow superclass to initialize its state first
    if (self = [super init]) {
    age = 0;
name = @“Bob”;
// do other initialization...
}
return self;
}
@end

여기에서 나오는 [super init]은 꼭 불러줘야 하는 필수 사항이며 그 값을 다시 self에 넣는 것은
혹시 슈퍼 클래스에서 다른 인스턴스를 돌려주는 특수 케이스가 있을수 있기 때문이다.
즉, 그냥 필요한 소스라고 생각하고 이 방식을 따라 주면 된다.


여러가지 초기화 메소드를 구현하고 싶을때 우리는 아래와 같은 방법을 쓸 수 있다.

- (id)init;
- (id)initWithName:(NSString *)name;
- (id)initWithName:(NSString *)name age:(int)age;


더 구체적인 값을 가진 초기화 메소드를 다시 불러 주는 방법이다.
이는 위의 self = [super init]과 같은 코드를 반복적으로 적어줘야 하는 불편함을 줄여 준다.

- (id)init {
return [self initWithName:@“No Name”]; //initWithName을 호출
}
- (id)initWithName:(NSString *)name {
return [self initWithName:name age:0]; //initWithName:age:를 호출
}


■ 메모리 관리

 생성  파괴
 C malloc free
Objective-c alloc dealloc


생성과 파괴는 같은 횟수 일어나야 한다.
하지만 Objective-c에서는 직접 dealloc을 부르지는 않는다.


참조 횟수(Reference Counting)

모든 오브젝트는 취득 횟수(Retain Count)를 가지고 있다.
    - NSObject에 정의 되어 있음
    - 취득 횟수(Retain Count) > 0 일 경우, 오브젝트는 유효하며 살아있다.
+alloc 이나 -copy는 오브젝트를 생성하며 취득 횟수(Retain Count) == 1로 만든다.
-retain 은 취득 횟수(Retain Count)를 1 증가시킨다.
-release 는 취득 횟수(Retain Count)를 1 감소시킨다.
취득 횟수(Retain Count)가 0이 될 때 오브젝트는 파괴된다.
    - dealloc 이 자동 실행된다.
    - 한번 dealloc 되면 다시 참조는 불가능 해진다.


Balanced Calls (동일한 횟수의 생성/파괴)

Person *person = nil;

person = [[Person alloc] init]; //오브젝트 생성

[person setName:@“Alan Cannistraro”];
[person setAge:29];
[person setWishfulThinking:YES];

[person castBallot];

// person 오브젝트의 사용이 끝나면 release한다.
[person release]; // person이 파괴될 것이다.


참조 횟수의 증감(Reference counting in action)
Person *person = [[Person alloc] init]; //+alloc에 의해 1이 된다.
[person retain]; //-retain에 의해 2가 된다.
[person release]; //-release에 의해 1이 된다.
[person release]; //-release에 의해 0이 된다. -deallocl 이 자동호출 된다.


참조 횟수가 0이 되어 dealloc된 person오브젝트를 만약 여기에서 다시 호출한다면 프로그램 이상으로 종료 될 것이다.
[person doSomething]; // Crash!


고로 이를 방지하기 위해, release 된 후 person = nil; 이라는 문장을 삽입 한다면 비록 참조되더라도 프로그램이 죽지는 않는다.
앞에서 설명했듯이 Objective-c에서는 nil오브젝트의 메소드를 호출해도 에러가 돌아오지 않기 때문이다.


Person *person = [[Person alloc] init];
// ...
[person release]; // Object is deallocated
person = nil;
[person doSomething]; // No effect (에러가 나지 않는다)


-dealloc 메소드 구현하기
#import "Person.h"
@implementation Person
- (void)dealloc {
// 필요한 cleanup을 적는다.
// ...
// 마지막에 슈퍼클래스의 dealloc을 불러준다.
[super dealloc];
}
@end


정리하면,

    오브젝트는 참조 횟수 1로 시작된다.
-retain과 -release로 참조 횟수가 증감한다.
참조횟수가 0이 되면 오브젝트는 자동으로 파괴된다.
절대 dealloc을 직접 호출해서는 안된다.
-[super dealloc]은 예외.
alloc, copy, retain, release 만 이용해라.

오브젝트의 소유권

Person이라는 오브젝트가 name이라는 속성을 가진다고 해보자.
@interface Person : NSObject
{
NSString *name; // Person class “owns” the name
}
@end


.m 파일에서 setter를 만들때,

1.retain을 사용
- (void)setName:(NSString *)newName {
if (name != newName) {
[name release];
name = [newName retain];
// retain을 사용한다면 name의 참조횟수는 1 증가하게 된다.
}

}

2.copy를 사용

- (void)setName:(NSString *)newName {
if (name != newName) {
[name release];
name = [newName copy];
// 혹은 copy를 사용한다면 name의 참조횟수는 1이 되며, 소유권이 생긴다.
}

}


retain대신 copy를 사용하는 이유는, 만약 수정 가능한 스트링 타입(NSMutableString)을 retain으로 넘겨 받는다면
밖에서 누군가가 이 값을 수정하였을때 파라메터로 넘겨받은 값도 영향을 받기 때문이다.
이를 방지하기 위해 영향을 받고 싶지 않을 경우에는 copy를 쓰도록 한다.


인스턴스 변수의 해방(release)

유저 정의 클래스 에서는 dealloc을 정의하여 필요한 cleanup을 적어준다.

#import "Person.h"
@implementation Person
- (void)dealloc {
    // 필요한 cleanup을 적어준다.
[name release];

// 슈퍼 클래스의 dealloc을 불러준다. 필수!!!
[super dealloc];
}


3. Autorelease

케이스 1
- (NSString *)fullName {
NSString *result;
result = [[NSString alloc] initWithFormat:@“%@ %@”, firstName, lastName];
    return result;
}
Wrong: result is leaked!

생성한 오브젝트를 릴리스 해주는 코드가 없어 잘못된 코드이다.


케이스 2
- (NSString *)fullName {
    NSString *result;
result = [[NSString alloc] initWithFormat:@“%@ %@”, firstName, lastName];
[result release];
return result;
}
Wrong: result를 너무 빨리 릴리스 했기때문에 잘못된 코드이다.


케이스 3
- (NSString *)fullName {
    NSString *result;
result = [[NSString alloc] initWithFormat:@“%@ %@”, firstName, lastName];
[result autorelease];
return result;
}

Just right: autorelease를 사용하면 result는 릴리스 되지만 바로 릴리스 되는것이 아니라 사용이 끝나면 릴리스 된다.


오브젝트의 자동릴리스(Autoreleasing Objects)

autorelease를 사용하면 즉시는 아니지만 필요한 시간이 경과된 후 release 명령이 오브젝트로 보내진다.
오브젝트를 일정시간 유지하고 싶을 때 retain/release를 충족하기 위하여 autorelease를 이용한다.
메모리 관리가 매우 효과적이다.
가장 유용하게 사용되는 부분은, 메소드내에서 새로 생성한 오브젝트를 돌려줄때 이다.


메소드 명과 자동릴리스(Method Names & Autorelease)
alloc이나 copy를 이용하여 오브젝트를 생성 하였을 경우, 생성한 사람은 이를 반드시 릴리스 해주어야 한다.

NSMutableString *string = [[NSMutableString alloc] init];
// -release 또는 -autorelease를 반드시 불러줄 것!
[string autorelease];


그 외 메소드들은 autorelease 오브젝트를 돌려줄 것이다.
NSMutableString *string = [NSMutableString string];
// 여기서는 alloc/copy를 사용하지 않고 오브젝트를 생성하였기 때문에

// autorelease 오브젝트가 생성 되므로 아무것도 안해도 된다.


유저 정의 클래스를 만들 경우에도 이 룰을 따라,

메소드내에서 오브젝트를 생성하였을 경우엔 autorelease 오브젝트를 돌려주도록 한다.


Autorelease의 작동 원리

오브젝트는 현재 자동릴리스 풀(current autorelease pool)에 저장된다.
자동릴리스 풀(autorelease pool)은 오브젝트가 릴리스 될수있도록 스케쥴링 한다.
    - 풀(pool) 자체가 릴리스 될 때, 풀은 모든 소유 오브젝트에게 -release 명령을 보낸다.
UIKit은 자동으로 이벤트 관련 풀을 포함(Wrap)하고 있다.


<어플리케이션의 시작~종료>
App 시작 ---> App 초기화 ---> main nib 로딩 ---> 이벤트 발생 대기 상태 ---> 이벤트 처리 ---> App 종료


여기의 이벤트 발생 대기 ~ 이벤트 처리 사이에서 발생한 이벤트는 자동으로 autorelease 모드로 풀에 들어가게 된다.

 <- 원본 pdf에서 발최


Autorelease 오브젝트를 릴리스 되지 않게 유지하는 방법

앞에서 다룬 룰에 의하면 많은 메소드 들은 Autorelease 오브젝트를 돌려주게 된다.
이 오브젝트들은 풀에 저장되어 있다가 시간이 경과하면 릴리스 되는데, 이를 릴리스 되지 않게 유지하고 싶다면
릴리스 되기 전에 -retain을 해주면 된다.


name = [NSMutableString string];
// 여기서 name을 retain하여 유효하게 유지 하게 된다.
[name retain];
// ...
// 사용이 끝나면 마지막에 release 해주도록 한다. (또는 클래스의 -dealloc에서 릴리스 할 수도 있다.)
[name release];


Garbage Collection

Autorelease는 Garbage Collection이 아니다.
iPhone OS의 Objective-c는 Garbage Collection을 지원하지 않는다. => 메모리 관리를 해야 한다는 뜻.


4.Property

클래스의 프로퍼티 선언은 @property와 @synthesize를 이용하여 간략화 할 수 있다는 것을 이전 문법 공부에서도 알아봤다.
추가로 몇가지 나열하자면 property와 인스턴스 변수의 이름은 다르게 설정 할 수 있다.


@interface Person : NSObject {
    int numberOfYearsOld;
}
@property int age;
@end

@implementation Person

//numberOfYearsOld라는 인스턴스 변수의 Getter/Setter를 age이라는 이름으로 정의.
@synthesize age = numberOfYearsOld;
@end

실제로 Property 가 사용 되고 있는 곳

새로운 API들은 @property를 사용한다.
기존 API들은 getter/setter를 사용한다.
기본 API 보다는 주로 UIKit API에 빈번히 사용되고 있다.
어느쪽을 사용해도 의미는 똑같다.
    @property는 적어야 하는 코드의 양을 줄여주지만, 때로는 코드 내용이 명확하지 않게 느껴질수도 있다.


■ .(Dot) 문법과 self

@interface Person : NSObject
{
NSString *name;
}
@property (copy) NSString *name;
@end

위와 같이 Person 오브젝트에 name 이라는 인스턴스 변수가 있다고 가정 할 때,
우리는 self.name과 같이 .(dot) 문법을 사용할 수 있다.
하지만 여기서 self.name은 name을 직접 호출 하는 것이 아니라 name의 setter/getter 메소드를 통해 접근 하게 된다.


그래서 만약 setter 메소드를 만들때 아래와 같은 실수를 하게 된다면 무한 루프에 빠지게 된다.

@implementation Person
- (void)setAge:(int)newAge {
    self.age = newAge; //이 코드는 [self setAge:newAge]를 호출하게 됨으로 자기자신을 계속 부르는 무한 루프가 된다.
}
@end


■ 읽어야 할 문서들

• Objective-C 2.0 Programming Language
    “Defining a Class”
    “Declared Properties”
• Memory Management Programming Guide for Cocoa


이해를 돕기 위해 위 문서를 읽고 넘어가면 도움이 될 것이다.



출처 : http://blog.naver.com/PostView.nhn?blogId=katchup00&logNo=10078813140
Posted by 오늘마감

댓글을 달아 주세요

아이폰어플개발정보2010. 6. 22. 17:54
유저 정의 클래스

역시나 과제 2의 내용을 복습(?)/해설 해주는 강의 이다.


유저 정의 클래스 (원문 - Custom Classes)

1. 유저 정의 클래스 생성하기
2. 오브젝트의 생명주기
3. Autorelease
4. Objective-C 속성(Properties)

1. 유저 정의 클래스 생성하기

클래스 디자인 하기

클래스 명을 정하고 슈퍼클래스를 정한다. 필요한 속성과 액션을 정의한다.


메소드(Methods), 셀렉터(Selectors), 메세지(Messages)의 차이와 복습

메소드는 오브젝트의 액션을 정의한 것이다.
- (NSString *)name
{
// 구현
}
- (void)setName:(NSString *)name
{
// 구현
}

셀렉터는 메소드를 참조하기 위한 이름이다. 콜론을 포함하지만 실제 파라메터나 타입은 포함하지 않는다.
SEL mySelector = @selector(name);
SEL anotherSelector = @selector(setName:);
SEL lastSelector = @selector(doStuff:withThing:andThing:);


메세지는 오브젝트의 셀렉터를 실행시키기 위한 방법이다. 필요에 따라 파라메터도 같이 적는다.
NSString *name = [myPerson name];
[myPerson setName:@“New Name”];


클래스 정의
(Public 헤더와 Private implementation)

.h 가 헤더이고 .m 이 소스 파일 이란것은 지금까지 해온 것이기 때문에 구지 다시 설명하지 않아도 될 것이다.

여기서 다시 한번 짚고 넘어 갈 부분은 자기 클래스의 메소드를 호출할때는 self를 사용하고,

슈퍼 클래스의 메소드를 호출할 때는 super를 사용한다는 것이다. self는 자바와 비교하면 자바의 this와 같은 개념이다.


<예>
[self doSomething]
[super doSomething]

2. 오브젝트의 생명주기(Object Lifecycle)

오브젝트의 생성에는 allocinit의 두 단계를 거친다. new는 alloc/init을 대신할수 있지만 별로 쓰이지 않는다.
왜냐하면 실 프로젝트에서는 init 대신 initWith라는 초기값을 가지는 (유저정의)초기화 메소드를 사용하는 경우가 더 많기 때문이다.

#import "Person.h"

@implementation Person
- (id)init {
    // allow superclass to initialize its state first
    if (self = [super init]) {
    age = 0;
name = @“Bob”;
// do other initialization...
}
return self;
}
@end

여기에서 나오는 [super init]은 꼭 불러줘야 하는 필수 사항이며 그 값을 다시 self에 넣는 것은
혹시 슈퍼 클래스에서 다른 인스턴스를 돌려주는 특수 케이스가 있을수 있기 때문이다.
즉, 그냥 필요한 소스라고 생각하고 이 방식을 따라 주면 된다.


여러가지 초기화 메소드를 구현하고 싶을때 우리는 아래와 같은 방법을 쓸 수 있다.

- (id)init;
- (id)initWithName:(NSString *)name;
- (id)initWithName:(NSString *)name age:(int)age;


더 구체적인 값을 가진 초기화 메소드를 다시 불러 주는 방법이다.
이는 위의 self = [super init]과 같은 코드를 반복적으로 적어줘야 하는 불편함을 줄여 준다.

- (id)init {
return [self initWithName:@“No Name”]; //initWithName을 호출
}
- (id)initWithName:(NSString *)name {
return [self initWithName:name age:0]; //initWithName:age:를 호출
}


■ 메모리 관리

 생성  파괴
 C malloc free
Objective-c alloc dealloc


생성과 파괴는 같은 횟수 일어나야 한다.
하지만 Objective-c에서는 직접 dealloc을 부르지는 않는다.


참조 횟수(Reference Counting)

모든 오브젝트는 취득 횟수(Retain Count)를 가지고 있다.
    - NSObject에 정의 되어 있음
    - 취득 횟수(Retain Count) > 0 일 경우, 오브젝트는 유효하며 살아있다.
+alloc 이나 -copy는 오브젝트를 생성하며 취득 횟수(Retain Count) == 1로 만든다.
-retain 은 취득 횟수(Retain Count)를 1 증가시킨다.
-release 는 취득 횟수(Retain Count)를 1 감소시킨다.
취득 횟수(Retain Count)가 0이 될 때 오브젝트는 파괴된다.
    - dealloc 이 자동 실행된다.
    - 한번 dealloc 되면 다시 참조는 불가능 해진다.


Balanced Calls (동일한 횟수의 생성/파괴)

Person *person = nil;

person = [[Person alloc] init]; //오브젝트 생성

[person setName:@“Alan Cannistraro”];
[person setAge:29];
[person setWishfulThinking:YES];

[person castBallot];

// person 오브젝트의 사용이 끝나면 release한다.
[person release]; // person이 파괴될 것이다.


참조 횟수의 증감(Reference counting in action)
Person *person = [[Person alloc] init]; //+alloc에 의해 1이 된다.
[person retain]; //-retain에 의해 2가 된다.
[person release]; //-release에 의해 1이 된다.
[person release]; //-release에 의해 0이 된다. -deallocl 이 자동호출 된다.


참조 횟수가 0이 되어 dealloc된 person오브젝트를 만약 여기에서 다시 호출한다면 프로그램 이상으로 종료 될 것이다.
[person doSomething]; // Crash!


고로 이를 방지하기 위해, release 된 후 person = nil; 이라는 문장을 삽입 한다면 비록 참조되더라도 프로그램이 죽지는 않는다.
앞에서 설명했듯이 Objective-c에서는 nil오브젝트의 메소드를 호출해도 에러가 돌아오지 않기 때문이다.


Person *person = [[Person alloc] init];
// ...
[person release]; // Object is deallocated
person = nil;
[person doSomething]; // No effect (에러가 나지 않는다)


-dealloc 메소드 구현하기
#import "Person.h"
@implementation Person
- (void)dealloc {
// 필요한 cleanup을 적는다.
// ...
// 마지막에 슈퍼클래스의 dealloc을 불러준다.
[super dealloc];
}
@end


정리하면,

    오브젝트는 참조 횟수 1로 시작된다.
-retain과 -release로 참조 횟수가 증감한다.
참조횟수가 0이 되면 오브젝트는 자동으로 파괴된다.
절대 dealloc을 직접 호출해서는 안된다.
-[super dealloc]은 예외.
alloc, copy, retain, release 만 이용해라.

오브젝트의 소유권

Person이라는 오브젝트가 name이라는 속성을 가진다고 해보자.
@interface Person : NSObject
{
NSString *name; // Person class “owns” the name
}
@end


.m 파일에서 setter를 만들때,

1.retain을 사용
- (void)setName:(NSString *)newName {
if (name != newName) {
[name release];
name = [newName retain];
// retain을 사용한다면 name의 참조횟수는 1 증가하게 된다.
}

}

2.copy를 사용

- (void)setName:(NSString *)newName {
if (name != newName) {
[name release];
name = [newName copy];
// 혹은 copy를 사용한다면 name의 참조횟수는 1이 되며, 소유권이 생긴다.
}

}


retain대신 copy를 사용하는 이유는, 만약 수정 가능한 스트링 타입(NSMutableString)을 retain으로 넘겨 받는다면
밖에서 누군가가 이 값을 수정하였을때 파라메터로 넘겨받은 값도 영향을 받기 때문이다.
이를 방지하기 위해 영향을 받고 싶지 않을 경우에는 copy를 쓰도록 한다.


인스턴스 변수의 해방(release)

유저 정의 클래스 에서는 dealloc을 정의하여 필요한 cleanup을 적어준다.

#import "Person.h"
@implementation Person
- (void)dealloc {
    // 필요한 cleanup을 적어준다.
[name release];

// 슈퍼 클래스의 dealloc을 불러준다. 필수!!!
[super dealloc];
}


3. Autorelease

케이스 1
- (NSString *)fullName {
NSString *result;
result = [[NSString alloc] initWithFormat:@“%@ %@”, firstName, lastName];
    return result;
}
Wrong: result is leaked!

생성한 오브젝트를 릴리스 해주는 코드가 없어 잘못된 코드이다.


케이스 2
- (NSString *)fullName {
    NSString *result;
result = [[NSString alloc] initWithFormat:@“%@ %@”, firstName, lastName];
[result release];
return result;
}
Wrong: result를 너무 빨리 릴리스 했기때문에 잘못된 코드이다.


케이스 3
- (NSString *)fullName {
    NSString *result;
result = [[NSString alloc] initWithFormat:@“%@ %@”, firstName, lastName];
[result autorelease];
return result;
}

Just right: autorelease를 사용하면 result는 릴리스 되지만 바로 릴리스 되는것이 아니라 사용이 끝나면 릴리스 된다.


오브젝트의 자동릴리스(Autoreleasing Objects)

autorelease를 사용하면 즉시는 아니지만 필요한 시간이 경과된 후 release 명령이 오브젝트로 보내진다.
오브젝트를 일정시간 유지하고 싶을 때 retain/release를 충족하기 위하여 autorelease를 이용한다.
메모리 관리가 매우 효과적이다.
가장 유용하게 사용되는 부분은, 메소드내에서 새로 생성한 오브젝트를 돌려줄때 이다.


메소드 명과 자동릴리스(Method Names & Autorelease)
alloc이나 copy를 이용하여 오브젝트를 생성 하였을 경우, 생성한 사람은 이를 반드시 릴리스 해주어야 한다.

NSMutableString *string = [[NSMutableString alloc] init];
// -release 또는 -autorelease를 반드시 불러줄 것!
[string autorelease];


그 외 메소드들은 autorelease 오브젝트를 돌려줄 것이다.
NSMutableString *string = [NSMutableString string];
// 여기서는 alloc/copy를 사용하지 않고 오브젝트를 생성하였기 때문에

// autorelease 오브젝트가 생성 되므로 아무것도 안해도 된다.


유저 정의 클래스를 만들 경우에도 이 룰을 따라,

메소드내에서 오브젝트를 생성하였을 경우엔 autorelease 오브젝트를 돌려주도록 한다.


Autorelease의 작동 원리

오브젝트는 현재 자동릴리스 풀(current autorelease pool)에 저장된다.
자동릴리스 풀(autorelease pool)은 오브젝트가 릴리스 될수있도록 스케쥴링 한다.
    - 풀(pool) 자체가 릴리스 될 때, 풀은 모든 소유 오브젝트에게 -release 명령을 보낸다.
UIKit은 자동으로 이벤트 관련 풀을 포함(Wrap)하고 있다.


<어플리케이션의 시작~종료>
App 시작 ---> App 초기화 ---> main nib 로딩 ---> 이벤트 발생 대기 상태 ---> 이벤트 처리 ---> App 종료


여기의 이벤트 발생 대기 ~ 이벤트 처리 사이에서 발생한 이벤트는 자동으로 autorelease 모드로 풀에 들어가게 된다.

 <- 원본 pdf에서 발최


Autorelease 오브젝트를 릴리스 되지 않게 유지하는 방법

앞에서 다룬 룰에 의하면 많은 메소드 들은 Autorelease 오브젝트를 돌려주게 된다.
이 오브젝트들은 풀에 저장되어 있다가 시간이 경과하면 릴리스 되는데, 이를 릴리스 되지 않게 유지하고 싶다면
릴리스 되기 전에 -retain을 해주면 된다.


name = [NSMutableString string];
// 여기서 name을 retain하여 유효하게 유지 하게 된다.
[name retain];
// ...
// 사용이 끝나면 마지막에 release 해주도록 한다. (또는 클래스의 -dealloc에서 릴리스 할 수도 있다.)
[name release];


Garbage Collection

Autorelease는 Garbage Collection이 아니다.
iPhone OS의 Objective-c는 Garbage Collection을 지원하지 않는다. => 메모리 관리를 해야 한다는 뜻.


4.Property

클래스의 프로퍼티 선언은 @property와 @synthesize를 이용하여 간략화 할 수 있다는 것을 이전 문법 공부에서도 알아봤다.
추가로 몇가지 나열하자면 property와 인스턴스 변수의 이름은 다르게 설정 할 수 있다.


@interface Person : NSObject {
    int numberOfYearsOld;
}
@property int age;
@end

@implementation Person

//numberOfYearsOld라는 인스턴스 변수의 Getter/Setter를 age이라는 이름으로 정의.
@synthesize age = numberOfYearsOld;
@end

실제로 Property 가 사용 되고 있는 곳

새로운 API들은 @property를 사용한다.
기존 API들은 getter/setter를 사용한다.
기본 API 보다는 주로 UIKit API에 빈번히 사용되고 있다.
어느쪽을 사용해도 의미는 똑같다.
    @property는 적어야 하는 코드의 양을 줄여주지만, 때로는 코드 내용이 명확하지 않게 느껴질수도 있다.


■ .(Dot) 문법과 self

@interface Person : NSObject
{
NSString *name;
}
@property (copy) NSString *name;
@end

위와 같이 Person 오브젝트에 name 이라는 인스턴스 변수가 있다고 가정 할 때,
우리는 self.name과 같이 .(dot) 문법을 사용할 수 있다.
하지만 여기서 self.name은 name을 직접 호출 하는 것이 아니라 name의 setter/getter 메소드를 통해 접근 하게 된다.


그래서 만약 setter 메소드를 만들때 아래와 같은 실수를 하게 된다면 무한 루프에 빠지게 된다.

@implementation Person
- (void)setAge:(int)newAge {
    self.age = newAge; //이 코드는 [self setAge:newAge]를 호출하게 됨으로 자기자신을 계속 부르는 무한 루프가 된다.
}
@end


■ 읽어야 할 문서들

• Objective-C 2.0 Programming Language
    “Defining a Class”
    “Declared Properties”
• Memory Management Programming Guide for Cocoa


이해를 돕기 위해 위 문서를 읽고 넘어가면 도움이 될 것이다.



출처 : http://blog.naver.com/PostView.nhn?blogId=katchup00&logNo=10078813140
Posted by 오늘마감

댓글을 달아 주세요