이번 강좌는 iPhone에서 각 애플리케이션들이 메모리를 관리하는 방법을 설명해 볼까 합니다. 기본적으로 Objective C에서는 Ref-counter를 사용해서 메모리를 관리합니다. COM을 생각해 보면 COM을 사용하는지 않아는지 참조 카운터를 통해서 확인을 하죠, DLL의 경우 AddRef ReleaseRef를 통해 카운터를 +,- 해주고 0이 되면 Unload 하는 방식으로... 동일하게 Objective C에서도 객체에 대한 메모리 관리를 참조 카운터로 해줍니다.  CString을 복사하면 Ref 만 늘린건지 객체 자체를 복사한 건지 확인 할 수 있다. 이처럼 NSObject를 상속 받은 객체들은 기본적으로 이 기능을 제공한다.

alloc : 간단히 객체를 생성 후 반환
copy : 기존의 객체를 복사한 후 Ref = 1로 변경
retain : 참조 권한 획득으로 Ref++ 해줌
release : Ref-- 해줌
autorelease : 음 이건 auto release라고 메모리를 관리하는 pool이 mac os상에 있다. 예를 들면 A라를 객체를 생성을 하고 autorelease 속성을 주면 따로 release 하지 않더라도 특정 시점 ( iphone 개발 동영상에서 본거 같은데 다시 볼려니까 귀찮고 그냥 기억 나는데로 말하면 ) 에 자동으로 ref를 내려서 메모리를 해지 한다는 것이다. 가비지 컬렉팅하고 비슷한 개념이다. 애플리케이션이 종료하는 부분이나 메모리 부족한 시점에 동작하는 것 같다. 물론 개발자가 auto release를 원하는 시점에 동작할 수도 있다.

지금까지 메모리 동작을 알아 보았다면 실제로 alloc 하는 코드를 만들어 보자. 이전 예제에서 많이 보았듯이..

id testObj = [[TestObject alloc]init];

으로 생성 및 초기화를 해준다.

반면에 해제는 ...

[testObject release];

로 해제해 준다.

[testObject retain];

한 경우에는

[testObject release];

를 꼭 해줘야 합니다.

아 auto release를 사용하는 이유가 또 있다. 예를 들어 function에서 alloc으로 객체를 생성하고 반환한다면, 어느 시점에서 release를 해줘야 할까? return하기 전에 바로 release 이건 좀 곤란하고 return 하고 나서 전달 결과를 전달 받은 함수에서? 이것도 좀 곤란하고 이럴 때 auto release를 사용하면 우선 생성한 객체를 return 하고 나중에 알아서 mac os상에서 release 해주게 한다.

참고 : 여기 훌륭한 예제가 있네요. 저는 게을러서..ㅎㅎ http://maclove.pe.kr/tag/autorelease

참고로 Stanford에서 만든 iPhone 개발에 관한 동영상을 itune에서 다운받아 보시면 잘 설명해 줍니다. 아! retain과 release를 짝을 안맞추면 어떻게 된다는 설명도..ㅎㅎ

http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocAllocInit.html#//apple_ref/doc/uid/TP30001163-CH22-105377

이렇게 Objective C에 대해서 설명을 간략하게 했으니, 다음에는 Xcode와 Interface Builder에 대해서 설명하도록 하겠습니다.

Objective C 세번째 강좌 Protocol and SEL

Apple 2010/03/30 00:00 posted by flankton
세번째 강좌는 Protocol인데 이 개념이 기존의 C/C++과 많이 다른 개념이라서 조금 낯설다. 그래도 간단히 코드를 보면서 설명해 보겠다.

※ 참고 (이전 강의에서 설명하지 못했던 부분) : 클래스의 interface에서 함수 선언 앞에 +,-의 의미는 class 함수의 경우 +, instance 함수의 경우 -를 붙인다. class 함수란? 이 설명이 맞는지 모르겠는데, alloc 또는 init , 생성자와 같이 class와 관련된 함수 반면에 instance method 는 생성 된 instance에 value를 참조 할 수 있는 method. 비유가 될지 모르겠지만 class는 static function이라고 보면 좀 비슷하지 않을까?

이제 진짜 procotol에 대해서 배워보자. Procotol은 왜 사용하는 걸까?  Apple의 DEV 사이트에서는 3가지 이류를 설명하고 있다.

  • To declare methods that others are expected to implement

  • To declare the interface to an object while concealing its class

  • To capture similarities among classes that are not hierarchically related

    구현 될꺼라고 예상 되는 함수를 선언할 때, 어떤 객체를 받았는데 그걸 쓸 수 있을지 없을지 모를때, 구조적으로 별 관련 없는 클래스들을 묶을 때(?) 라고 설명하고 있다.
  • 예제를 살펴 보면 대략, MFC의 RUNTIME OBJECT CHECK 과 비슷한 것 같다. 예를 들면 A라는 객체를 받아서 처리하는데, A라는 객체가 어떤 함수가 구현이 되서 호출 할 수 있는지 확인하는 방법인 것 같다.

    그럼 간단히 구현을 해보자.

    @protocol TestProtocol
    -(void)IAgreeProtocol;
    @end

    이렇게 TestProtocol.h 파일을 작성하면 프로토콜이 만들어진 것이다. 그럼 이 프로토콜을 어떻게 사용할까?
    MyStone.h 와 MyStone.m을 만들어서 MyStone이 Protocol을 준수하도록 해 보자.

    MyStone.h에 아래와 같이 추가를 한다.

    #import "TestProtocol.h"

    @interface MyStone: NSObject<TestProtocol> {
    }
    @end


    그리고 구현은 아래와 같이 한다.

    @implementation MyStone
    -(void)IAgreeProtocol{
      NSLog(@"I agree you!");
    }
    @end


    아 그럼 이 프로토콜로 객체를 구별할 수 있는 코드를 구현해 보자~!

    id testObj = [[MyStone alloc]init];
    if ( [testObj conformsToProtocol:@protocol(TestProtocol)]) {
       [testObj IAgreeProtocol];
    }


    이렇게 코드를 작성하면, testObj를 생성하고 TestProtocol을 준수하기 때문에 아래의 IAgreeProtocol 메세지를 호출 할 수 있다.

    그럼 SEL을 알아보자. SEL은 함수 포인트 같다고 한다. 사실 이런 개념이 좀 애매했는데, 예를 보면 좀 감이 올 것 같다.

    SEL print_item;
    print_item = @selector(PrintItem);
    [hometown performSelector:print_item];


    print_item은 객체의 PrintItem이라는 이름을 갖는 함수의 포인터를 저장한다. 그게 바로 SEL type의 변수 그리고 hometown의 객체의 함수(메세지)를 호출 할때는 performSelector를 통해 호출한다. 그럼 바로 호출이 된다. 그렇다면 print_item의 이름을 바꿔주면 어떤 객체의 함수(메세지)를 호출 할 수 있다는 말!

    반대로 SEL 에서 함수이름을 얻을 수 있다. 예를 들면

    NSString *method;
    method = NSStringFromSelector(print_item);


    이렇게  그러면 아마 method 는 PrintItem 일 것이다. Objective C의 동적인 면을 보여주는 키워드인 것 같다.

    참고 : objective C에 대한 간단한 예제가 있는 사이트
    http://www.otierney.net/objective-c.html#gettingstarted

    Objective C 두번쨰 강좌 Property and Synthesize

    Apple 2010/03/29 23:34 posted by flankton

    C++에서 클래스는 멤버 함수와 맴버 변수로 구성 되어 있는데, Objective C도 OOP 개념 때문에 동일하다. 이번에는 맴버 변수를 넣고 값을 설정하는 코드를 작성해 보겠다.

    C++과는 용어가 다르게 state와 behavior라고 한다. state는 맴버 변수, behavior는 맴버 함수?

    그럼 Property와 Synthesize는 뭐지? state를 쉽게 맴버 변수와 함수를 등록하는 방법이다. Java의 getter,setter 함수와 같은...  자~ 그럼 간단한 예제를 만들어 보자.

    지난 강좌에서 만든.... AppleMarket에 추가해 보겠다.

    @interface AppleMarket: NSObject {
       NSString* item;
    }
    @property (copy,readwrite) NSString@ item;
    -(void)Buy:(NSString*)arg;
    @end


    NSString@ item;
    @property (copy,readwrite) NSString@ item; 
    interface에 코드를 추가하였다. 그럼 구현은 어떻게 하면 될까?

    구현은 간단히 @synthesize item을 추가해 주면 된다.

    @implementation AppleMarket
    @synthesize item;
    -(void)Buy:(NSString*)arg {
       item = arg;
      printf("%s",[arg cStringUsingEndcoding:1]);
    }
    @end


    자 그럼 @synthesize를 어떻게 setter, getter 함수를 호출 할 수 있을까? setItem 과 같이 set(대문자)변수명으로 호출해 줄 수 있다. 위의 예를 들면 아래와 같이....

    [hometown setItem:@"Orange"];

    이렇게 호출하면 item 값이 Orange로 변경 된 것을 볼 수 있다. NSLog(item); 으로 콘솔에서 확인하면 된다.
    그럼 이렇게 set(대문자)변수명 으로 setter와 getter를 만들어야만 하나?? 그렇지는 않다.

    @property(getter=getItemName,copy,readwrite) NSString* item;

    Property를 선언해 주면 된다. setter도 동일하다. 그런데 copy , readwrite는 뭐지?
    copy는  setter의 동작이고 readwrite는 값에 대한 쓰기 속성이다. setter 속성에는 assign,retain,copy,nonatomic 이 있다. 각각을 보면 assign은 값을 대입한다. retain은 이전 값은 release하고 다시 대입한다. copy는 값을 복사해서 대입한다. nonatomic은 비원자화??? 응?응? 기본적으로 atomic하게 동작하기 때문에 nonatomic이라는 게 있다고 한다. Database의 atomic과 같은 개념인가?

    setter의 속성에는 readwrite가 있고 readonly가 있는데, readonly로 하면 getter밖이 사용할 수 없다. setter를 사용하면 compile가 싫어한다.

    끝~