본문 바로가기

Thinking/Study

Objective-C 에서 Properties, iVar 설명

728x90

애플 문서에서 찾은 Objective-C 의  iVar(instance variable) 를 설명한 내용과 예제입니다. 다른 책에서 참고한 내용을 같이 정리합니다.


다음과 같은 코드에서 인스턴스 initWithTitle 메소드내의 _(underscore) 를 가진 변수들(_titile, _artist,..) 들을 iVar(instance variable; 이하 인스턴스 변수)라고 한다. 

(추가로 @implementation 영역에서 선언한 변수들도 iVar 입니다. 인스턴스 변수들의 생명주기는 객체 생성, 소멸에 따릅니다. 프로퍼티로 선언된 변수들을 객체가 완전하지 않은 상태(alloc(), init()) 에서 사용하기 위해서는 _(언더스코어) 표기법을 따르는게 좋습니다. (from Pro Objective-C chapter 2:Using Classes, Keith Lee, Apress))

#import <Foundation/Foundation.h>


@interface Album : NSObject

@property (nonatomic, copy) NSString *title;

@property (nonatomic, copy) NSString *artist;

@property (nonatomic, copy) NSString *summary;

@property (nonatomic, copy) NSString *locationInStore;


@property (nonatomic, assign) float price;


-(id)initWithTitle:(NSString *)title artist:(NSString *) artist summary:(NSString *)summary price:(float)price locationInStore:(NSString *)locationInStore;

@end


@implementation Album


-(id)initWithTitle:(NSString *)title artist:(NSString *)artist summary:(NSString *)summary price:(float)price locationInStore:(NSString *)locationInStore {

    self = [super init];

    if (self) {

        _title = title;

        _artist = artist;

        _summary = summary;

        _price = price;

        _locationInStore = locationInStore;

        

        return self;

    }

    return nil;

}

@end


대부분의 프로퍼티는 인스턴스 변수에 의해 뒷바침된다(be backed)

 프로퍼티(property) 는 인스턴스 변수에 의해서 뒷바침되고, 다시 컴파일러에 의해서 자동으로 합성(synthesized : 컴파일러가 setter/getter 를 자동 생성한다)된다.

 인스턴스 변수는 객체의 생존 주기 동안 존재하고 값을 유지하는 변수이다. 인스턴스 변수에서 사용된 메모리는 객체가 처음 생성될때(alloc 메소드를 통해) 할당되고 객체가 해제될때(dealocated) 사라진다.(freed)

 특별히 지정하지 않는다면 합성된(synthesized) 인스턴스 변수는 _(underscore) 접두어(prefix)를 가진거 외에는 프로퍼티와 동일한 이름을 가진다. 예를 들어 firstName 프로퍼티의 합성된 인스턴스 변수는 _firstName 이다.

객체 자신의 프로퍼티들에 접근하는 가장 좋은 방법은 접근자(accessor) 메소드 또는 .(dot) 표기법이지만 구현된 클래스에 있는 인스턴스 메소드에서 직접 인스턴스 변수로 접근할 수 있다. 위의 예 initWithTitle: 이 해당한다.


- (void)someMethod {

    NSString *myString = @"An interesting string";

 

    _someString = myString;

}

 예에서 myString 은 지역 변수(local variable) 이고, _someString 은 인스턴스 변수이다.

 대개 자신의 구현체(implementation) 내에서 객체의 프로퍼티들을 접근할 경우, 접근자 메소드나 도트(.) 식(syntax) 를 사용한다면 self: 를 사용해야 한다.

- (void)someMethod {

    NSString *myString = @"An interesting string";

 

    self.someString = myString;

  // or

    [self setSomeString:myString];

}


합성된 인스턴스 변수를 커스텀할 수 있다

 쓰기 가능한 프로퍼티는 _propertyName 으로 불리는 인스턴스 변수를 사용할 수 있다.

인스턴스 변수에 다른 이름을 사용하길 원한다면 구현체에서 다음 문법으로 컴퍼일러에게 변수를 합성하도록 가리킬 필요가 있다.

@implementation YourClass

@synthesize propertyName = instanceVariableName;

...

@end


예를 들어

@synthesize firstName = ivar_firstName;

 이 경우에 프로퍼티는 firstName 으로 호출되고, firstName 와 setFirstName: 을 통해 접근자 메소드나 도트식으로 접근할 것이고, ivar_firstName 으로 불리는 인스턴스 변수로 뒷받침될 수 있다.(backed)


만약 @synthesize 를 다음과 같이 인스턴스 변수없이 사용한다면, 인스턴스 변수는 프로퍼티와 동일한 이름을 가질 것이다. 이 예에서 인스턴스 변수는 _가 없는 firstName 으로 불릴 것이다.

@synthesize firstName


(위의 예제들에서 나온거처럼 @synthesize 를 프로퍼티 변수에 지정하면 원하는 변수명으로 사용할 수 있지만, @synthesize 를 굳이 지정안해도 컴파일러가 자동으로 autosynthesis 를 적용하여서 _(언더스코어)를 붙이면 사용할 수 있게됩니다. 위의 Album 클래스에서 사용한 방식입니다. (from Pro Objective-C chapter 2:Using Classes, Keith Lee, Apress))


: Pro Objective-C 에서 설명한 예제(Elements 라는 프로젝트에 Atom 클래스를 선언)

- Atom.h

//

//  Atom.h

//  Elements

//

//  Created by Jeon BooSang on 2014. 12. 3..

//  Copyright (c) 2014 Jeon BooSang. All rights reserved.

//


#import <Foundation/Foundation.h>


@interface Atom : NSObject

@property (readonly) NSUInteger protons;

@property (readonly) NSUInteger neutrons;

@property (readonly) NSUInteger electrons;

@property (readonly) NSString *chemicalElement;


@property int abc;


- (NSUInteger) massNumber;

@end

- Atom.m

//

//  Atom.m

//  Elements

//

//  Created by Jeon BooSang on 2014. 12. 3..

//  Copyright (c) 2014 Jeon BooSang. All rights reserved.

//


#import "Atom.h"


@implementation Atom

//@synthesize chemicalElement;// = chemicalElement;

@synthesize abc;


- (id) init

{

    if ((self = [super init]))

    {

        _chemicalElement = @"None";      // synthesize 가 선언이 안되어있지만 자동생성된 인스턴스변수

    }

    abc = 1;

    return self;

}


- (NSUInteger) massNumber

{

    return 0;

}


@end

- main.m

//

//  main.m

//  Elements

//

//  Created by Jeon BooSang on 2014. 12. 3..

//  Copyright (c) 2014 Jeon BooSang. All rights reserved.

//


#import <Foundation/Foundation.h>

#import "Atom.h"


int main(int argc, const char * argv[]) {

    @autoreleasepool {

        Atom *atom = [[Atom alloc] init];

        atom.abc = 123;

        [atom setAbc:123];

        NSLog(@"Hello, World!");

    }

    return 0;

}

Atom 클래스의 abc 프로퍼티를 두가지 방식(dot 표기법과 setter 이용)으로 값을 저장하고 있습니다.


※ auto synthesis 기능은 Xcode 4.4(LLVM 2.0) (: 2012년 7월 20일 ~) 에서 부터 적용이 되었다고 합니다. (https://en.wikipedia.org/wiki/Xcode)


출처 :

https://developer.apple.com/library/ios/documentation/cocoa/Conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html

http://stackoverflow.com/questions/9086736/why-would-you-use-an-ivar

http://phildow.net/2012/08/13/auto-synthesize-in-xcode-4-4-even-handier-than-you-thought/