검색결과 리스트
objective에 해당되는 글 1건
- 2011.03.20 Objective-C 훑어보기 (2)
글
Objective-C 훑어보기
Objective-C
2011. 3. 20. 23:40
iPhone 의 인기와 더불어 주목받고 있는 Objective-C 언어에 대해서 간략히 알아보자.
Objective-C 언어는 C 언어 기반위에 객체지향적인 요소를 가미한 언어로서, 객체지향 언어의 원류인 Smalltalk 에서
그 개념을 많이 차용했다고 한다. 이 포스팅에서는 언어의 구체적인 설명은 하지않고, 간략히 어떤 언어 요소들이
있는지만 알아보겠다.
Objective-C 언어는 C 언어 기반위에 객체지향적인 요소를 가미한 언어로서, 객체지향 언어의 원류인 Smalltalk 에서
그 개념을 많이 차용했다고 한다. 이 포스팅에서는 언어의 구체적인 설명은 하지않고, 간략히 어떤 언어 요소들이
있는지만 알아보겠다.
1. Objective-C 에서 클래스 정의
#import "SuperClass.h"
@interface NewClass : SuperClass {
int instanceVariable;
}
- method;
- methodWithParameter:param;
@end
@implementation NewClass
- method {
return (nil);
}
- methodWithParameter:param {
return (nil);
}
2. Object Pointers
SpecificClass * specificObject; id anyObject;id 타입은 void * 형 포인터로 어떤 객체 포인터도 할당하거나 할당받을 수 있다.
3. Sending Messages
[object method]; [object methodWithParam:param];
objective-c에서는 메시지를 호출한다고 하기 보단, 객체에게 메세지를 보낸다고 한다.
3. Naming Method
Objective-C에서는 메시지의 이름을 부여할 때, 메소드가 취하는 행위를 기술하도록 이름짓는다. 메시지의 이름은
다음과 같은 형식을 따른다.
다음과 같은 형식을 따른다.
반환타입+메시지행위+첫번째 인자이름: 첫번째 인자 이름: 두번째 인자이름...
반환타입이나 인자가 존재하지 않는 경우 생략될 수 있다.
- valuePrepositionParameter:parameter - objectForKey:key - stringByAppendingString:string; - numberFromString:string;
4. Parameter and Return Types
인자와 반환값은 괄호사이에 기술한다- (id)objectForKey:(id)aKey; - (NSMenuItem)itemWithTag:(NSInteger)aTag; - (unichar)characterAtIndex:(NSUInteger)index; - (NSString*)stringByAddingPercentEscapeUsingEncoding:(NSStringEncoding)encoding; - (void)runInNewThread; - (void)addAttribute:(NSString*)name value:(id)value range:(NSRange)aRange;
5. Method Selectors
메서드의 이름, 인자변수의 이름, 인자의 타입이 유일한 식별자를 구성하며, Java 의 메소드 시그니처와 동일한 의미를 갖는다.
(NSfont*)fontWithFamily:(NSString*)family traits:(NSFontTraitMask)fontTraitMask weight:(NSInteger)weight size:(CGFloat)size
의 메소드 식별자는 fontWithFamily:family:traits:weight:size 가 된다. 이 식별자는 실제로 selector 라 불리는 숫자 상수와
맵핑이 되며, 그 숫자 상수는 SEL 타입을 갖는다. @selector() 지시어는 특정 메소드의 selector 상수를 반환한다
SEL selector = @selector(fontWithFamily:traits:weight:size)
6. Instance Variable
isa 인스턴스 변수
모든 Objective-C 객체가 상속받는 인스턴스 변수로, 클래스 자체를 정의하는 Class 타입의 객체이다.
- (Class)class 메소드 호출을 통해 얻을 수 있으며, - (NSString *)className 통해 클래스의 이름을 문자열로 얻을 수 있다.
Properties
객체의 프로퍼티를 정의하는 키워드로 @property 와 @synthesize 가 있다. @property 는 클래스가 계약을 지킬 것이라고 컴파일러에게 알려주는 역할을 한다. @synthesize 는 컴파일러에게 해당 인스턴스 변수에 대한 getter와 setter 를 생성하라고 지시한다
int tag;
라는 인스턴스 변수에 대해 @property int tag; @synthesize tag;를 선언되면 컴파일러는
- (void)setTag:(int)newTag
- (int)tag
- (int)tag
와 같은 한쌍의 접근자를 생성할 것이다. 이렇게 생성된 접근자는 디폴트로 threadsafe 하다. @property만 선언했다면, 구현파일에
getter 와 setter를 기술하는 것은 프로그래머의 몫이다. 즉 @synthesize를 통해 자동생성하거나, 프로그래머가 직접 구현해줘야 한다. 그렇지 않으면 컴파일 에러가 발생할 것이다.
getter 와 setter를 기술하는 것은 프로그래머의 몫이다. 즉 @synthesize를 통해 자동생성하거나, 프로그래머가 직접 구현해줘야 한다. 그렇지 않으면 컴파일 에러가 발생할 것이다.
@property 지시어와 함께 사용할 수 있는 속성들이 있는데, getter와 setter울 생서을 위한 속성이 된다.
Property Attributes
| Attribute | Description |
| readonly | getter 만을 생성한다. readwrite 속성과 상반된다. |
| readwrite | 디폴트 값이며, getter 와 setter 를 모두 생성한다. |
| copy | setter 에서 인자를 인수변수에 저장할 때, 인자의 복사본을 저장한다. 객체 포인터 타입에만 유효한 속성이다. (primitive 타입은 항상 복사되기 때문) 리시버가 센더의 인자값을 변경하지 못하게 할 때 사용한다. |
| assign | 인스턴스 변수에 레퍼런스 카운팅 없이 단순 할당한다. 가비지 컬렉션이 존재하는 환경에서 참조를 유지하고 싶거나, 인자값이 변경불가능할 때 사용한다. |
| retain | assign과 유사하며, 가비지 컬렉션이 없는 Managed memory 환경에서 객체의 참조 카운터를 증가 시킨다. |
| getter=name | 지정한 name 이름으로 getter 를 생성한다. getter와 setter의 표준 패턴을 위반해서 Key-Value Coding 과 같은 기술들이 인식할 수 없게 될수도 있기 때문에 사용에 주의해야한다. |
| setter=name | 지정한 name 이름으로 setter 를 생성한다. |
| nonatomic | 디폴트로 생성된 setter 는 atomic 속성을 갖는다. 락을 사용하여 thread-safe 하지만, 상당한 오버헤드를 수반한다. 쓰레드의 개입이 없을 경우, 명시적으로 nonatomic 으로 선언하여 performance 를 높이는게 좋다. |
7. Class Methods
클래스 메소드는 메소드 이름 앞에 + 기호를 갖는다. 모든 클래스는 런타임에 그 클래스 인스턴스의 identity와 behavior를 정의하는
하나의 Class 객체를 생성한다. 클래스는 이 Class 객체가 응답하는 메시지를 정의한다. Objective-C의 클래스 메소드는 자바와 비슷한 역할을 하지만 기술적으로는 다르다.
@interface RandomSequece : NSObject {
long long int seed;
}
+ (NSNumber*)number;
+ (NSNumber*)string;
- (NSNumber*)nextNumber;
- (NSString*)string;
@end
...
NSNumber *n = [RandomSequence number];
NSString *s = [RandomSequence string];
관례적으로 클래스 메소드를 먼저 정의하고, 인스턴스 메소드를 정의한다. 자바에서 클래스메소드는 this 키워드를 사용할 수 없지만, Objective-C 의 클래스메소드 에서는 self 키워드를 사용할 수 있다. 클래스 메소드에 self 는 Class 객체를 가리키며, 인스턴스 메소드 처럼 서브클래스에 상속할 수 있으며 오버라이딩 또한 가능하다.
@interface Classy : NSObject {
+ (void)greeting;
+ (NSString*)salutation;
}
@end
@implementation
+ (void)greeting {
NSLog(@"%@, world!", [self salutation]);
}
+ (NSString*)salutation {
NSLog(@"Greetings");
}
@end
@interface Classic : Classy
+ (NSString*)salutation;
@end
+ (NSString*)salutation {
return (@"Hello");
}
@end
...
[Classy greeting]; // Logs "Greetings, world"
[Classic greeting]; // Logs "Hello, world!"
[Classic greeting] 은 Classy Class 객체에 메시지를 보내고, [self salutation]은 해당 Cass 클래스 객체에 메시지를 보낸다.
[Classic greeting] 은 greeting 메소드가 없지만, 수퍼클래스로부터 상속받은 greeting 메시지를 호출하며, [self salutation] 은 Classic
Class 객체에 메시지를 보낸다.
Class 객체에 메시지를 보낸다.
8. Constructing Objects
java 에서는 객체를 생성하는 문법을 존재하여, 객체를 생성하는 방법을 명시적으로 제약한다. 반면 Objective-C 는 객체를
생성하는 방법을 클래스 설계자가 결정하도록 한다.
생성하는 방법을 클래스 설계자가 결정하도록 한다.
객체를 생성하는 과정은 2가지 과정을 거친다.
1) 메모리 구조 할당
2) 인스턴스 초기화
@interface RandomSequence : NSObject {
long long seed;
}
- (id)init;
- (id)initWithSeed:(long long)startingSeed;
@end
@implementation RandomSequence
- (id)init {
self = [super init];
if (self != nil) {
seed = 1;
}
return (self);
}
- (id)initWithSeed:(long long)startingSeed {
self = [super init];
if (self != nil) {
seed = startingSeed;
}
return (self);
}
@end
...
RandomSequence *r1 = [[RandomSequence alloc] init];
RandomSequence *r2 = [[RandomSequence alloc] initWithSeed:-43 ];
RandomSequence * r3 = [RandomSequence new];
alloc 은 NSObject 에 정의된 클래스 메소드 +(id)alloc 이다. 객체를 생성하기 위해 클래스 참조를 사용하여 메모리를 할당하고,
그것을 isa 변수에 할당한다. 그리고 인스턴스를 모두 0으로 채운뒤, 참조를 반환한다. 이 시점에서 요청된 객체가 존재하지만
아직 초기화는 되지않았다. init 메시는 객체를 초기화를 담당하며, 이메시지가 반환되면 깨체는 사용할 준비가 된 상태가 된다.
그것을 isa 변수에 할당한다. 그리고 인스턴스를 모두 0으로 채운뒤, 참조를 반환한다. 이 시점에서 요청된 객체가 존재하지만
아직 초기화는 되지않았다. init 메시는 객체를 초기화를 담당하며, 이메시지가 반환되면 깨체는 사용할 준비가 된 상태가 된다.
new 도 NSObject의 클래스 메소드로 내부적으로 alloc과 init 를 호출한다
- (id)init...계열의 메소드를 오버라이드 하거나 재정의 해서 객체생성을 커스터마이징 할 수 있다.
+ (id)alloc 또는 +(id)new 를 재정의 해서는 안된다.
9. Writing an init Method
9. Writing an init Method
Objective-C에서 생성자를 작성하기 위해서 4가지 계약을 충족해야 한다
1) 수퍼 클래스의 생성자를 호출한다 : [super init]
2) 자신의 self 변수를 업데이트 한다 : self = [super init]
3) nil 객체 검사를 한다 : if (self != nil ) { ... }
4) 자신의 포인터를 반환한다 : return self
모든 생성자는 수퍼클래스의 생성자를 호출해야한다. 자바는 언어 차원에서 이를 지원하지만, Objective-C 는 프로그래머에게
책임이 있다. self 를 변경하는 것은 자바 프로그래머에게는 이상하지만, Class Cluster를 위해 핵심이 되는 부분이다.
책임이 있다. self 를 변경하는 것은 자바 프로그래머에게는 이상하지만, Class Cluster를 위해 핵심이 되는 부분이다.
nil 객체 검사를 하는 이유는, 반드시 메모리 할당이 성공한다고 보장할 수 없기 때문이다. 메모리 고갈로 인한 실패가 있을 수 있기
때문에 방어적인 프로그램을 위한 것이다. 모든 잘 작성된 생성자는 위의 4가지 조건을 만족해야 한다
때문에 방어적인 프로그램을 위한 것이다. 모든 잘 작성된 생성자는 위의 4가지 조건을 만족해야 한다
Chaining Initializers
자바에서는 명시적인 생성자 호출 문법을 가지고 있어서, 특정한 수퍼클래스의 생성자나 자신의 생성자를 호출 할 수 있다.
Objective-C에서는 이러한 문법은 없지만, 동일한 원리로 수퍼클래스나 자신의 init...계열의 메시지로 초기화가 가능하다.
Designated Initializer
Objective-C 의 많은 클래스들이 "설계된" 생성자를 갖으며, 객체 생성시 이를 사용하여 초기화를 해야한다
그렇기 때문에 이러한 클래스들을 사용할 경우에는 문서를 참조해야 한다.
Convenience Constructors
클래스 메소드의 일반적인 용례는 복잡한 객체 생성 및 초기화를 간소화시킷는 것이다.
Cocoa framework의 NSDictrionary 클래스는 [NSDictionary dictionary] 클래스 메소드를 제공하며, 이것은
[[NSDictionary alloc] init] 와 동일하다
Objective-C 에서도 선택적으로 - (void)finalize 메소드를 오버라이드 할수 있다. 이 메시지는 가비지 컬렉터에 의해 객체가 파괴되기
전에 호출된다. 모든 finalize 메소드는 반환되기 직전에 수퍼클래스의 finalize 메시지를 호출해야한다
- (void)finalize {
if (file != nil) {
[file close];
file = nil;
}
[super finalize]
}
11. etc...
Inner / Anonymous Classes (내부 클래스와 익명클래스)
Inner / Anonymous Classes (내부 클래스와 익명클래스)
내부 클래스와 익명클래스는 코드 캡슐화나 어댑터로 사용되는데, Objective-C 에서는 비공식 프로토콜과 코드 블록을
사용하여 구현된다. (코드 블록은 변수에 실행가능한 코드 블록 할당을 허용하는 Objective-C 언어에 최근 추가된 개념이다)
Object Arrays
Objecitve-C에서는 C object 포인터 배열이나 NSArray 컬렉션 클래스를 사용하여 구현한다
final
final 키워드를 지원하지 않으며, 클래스 상속이나 메소드 오버라이딩을 막을 수 없다. 변수에 적용 할 경우, const가 유사하다.
abstract
Objective-C 의 모든 클래스와 메소드는 구체 클래스이다
package
Objective-C에는 패키지가 없으며, 패키지 범위 또한 없다.
'Objective-C' 카테고리의 다른 글
| Objective-C 문자열 조작 메서드 (0) | 2011.04.29 |
|---|---|
| 다중인자를 갖는 PerformSelector 메시지 (0) | 2011.03.23 |
| Protocol 과 Category (0) | 2011.03.22 |
| Objective-C 훑어보기 (2) | 2011.03.20 |
| [Cocoa] Cocoa Design Pattern (0) | 2011.03.20 |
| HMAC-SHA1 구현 (0) | 2011.03.03 |