
@interface : 클래스, 메서드 선언@implementation : 메서드 구현Objective-C에서는 첫 번째 매개변수에는 별도 이름을 붙일 수 없다.
(대신 메서드 이름 자체를 더 직관적으로 만들어서 해결해야 한다.)
-와 +는 메서드가 인스턴스 메서드인지, 클래스 메서드인지를 나타내는 구분자
| 기호 | 의미 |
|---|---|
| - (빼기) | 인스턴스 메서드 (객체를 통해 호출됨) |
| + (더하기) | 클래스 메서드 (클래스 자체에서 호출 가능) |
#import <Foundation/Foundation.h>
@interface SampleClass : NSObject
// 메서드 선언
- (void)print;
- (void)setNumber: (int)num1 setAnotherNum: (int)num2;
- (int)plusNumber;
- (int)minusNumber;
@end
@implementation SampleClass
int firstNum;
int secondNum;
- (void)print {
NSLog(@"%i, %i", firstNum, secondNum);
}
- (void)setNumber: (int)num1 setAnotherNum:(int)num2 {
firstNum = num1;
secondNum = num2;
}
- (int)plusNumber {
return firstNum + secondNum;
}
- (int)minusNumber {
return firstNum - secondNum;
}
@end
// 프로그램 부분
int main(int argc, const char * argv[]) {
@autoreleasepool {
// SampleClass *sampleClass = [SampleClass alloc]; // 메모리 공간 할당
// sampleClass = [sampleClass init]; // 초기화
// SampleClass *sampleClass = [[SampleClass alloc] init]; // 한 줄로 결합 가능
SampleClass *sampleClass = SampleClass.new; // 대체 가능
[sampleClass setNumber:4 setAnotherNum:3];
int sum = [sampleClass plusNumber];
NSLog(@"%i", sum);
int minus = [sampleClass minusNumber];
NSLog(@"%i", minus);
[sampleClass print];
}
return 0;
}
@interface SampleClass : NSObject {
int height;
}
- (void)setHeight:(int)height;
- (int)getHeight;
@end
@implementation SampleClass
- (void)setHeight:(int)newHeight {
height = newHeight;
}
- (int)getHeight {
return height;
}
@end
int main(void) {
SampleClass *sampleClass = [[SampleClass alloc]init];
[sampleClass setHeight:4];
NSLog(@"%d", [sampleClass getHeight]);
}
@interface SampleClass : NSObject
@property int height;
@end
@implementation SampleClass
@end
int main(void) {
SampleClass *sampleClass = [[SampleClass alloc]init];
sampleClass.height = 4;
NSLog(@"%d", sampleClass.height);
}
case1, case2 코드의 동작은 동일하지만 case2처럼 @property를 사용하는 것이 편리 + 안전하다.
struct Book {
NSString *title;
NSString *author;
int bookID;
};
@interface SampleClass : NSObject {
struct Book myBook;
}
- (void)setBook:(NSString *)title author:(NSString *)author bookID:(int)bookID;
- (void)printBook;
@end
@implementation SampleClass
- (void)setBook:(NSString *)title author:(NSString *)author bookID:(int)bookID {
myBook.title = title;
myBook.author = author;
myBook.bookID = bookID;
}
- (void)printBook {
NSLog(@"Title: %@", myBook.title);
NSLog(@"Title: %@", myBook.author);
NSLog(@"Title: %d", myBook.bookID);
}
@end
int main(void) {
SampleClass *sampleClass = [[SampleClass alloc]init];
[sampleClass setBook:@"파우스트" author:@"괴테" bookID:1234];
[sampleClass printBook];
}
@interface Box : NSObject {
double length;
double breath;
double height;
}
@property(nonatomic, readwrite) double height;
- (double) volume;
@end
@implementation Box
@synthesize height;
- (id)init {
length = 1.0;
breath = 1.0;
return self; // 현재 객체(self)를 반환
}
- (double) volume {
return length * breath * height;
}
@end
int main(void) {
Box *box1 = [[Box alloc]init];
box1.height = 10;
NSLog(@"%f", [box1 volume]);
}
@property 사용시 getter/setter을 자동으로 생성되기 때문에 명시하지 않아도 된다.
id는 Objective-C에서 모든 객체 타입을 나타내는 동적 타입이다. 간단히 말하면, 어떤 클래스의 객체가 될 수 있는 모든 객체를 나타내는 타입이다.(구체적인 클래스 타입을 명시하지 않고 모든 객체를 받아들일 수 있다.)
| 속성 | 의미 |
|---|---|
| nonatomic | 멀티스레드 안전성 보장 X, 성능 빠름 (일반적으로 사용) |
| atomic | 멀티스레드에서 안전하지만 성능 저하 |
| strong | 객체를 소유하며 해제되지 않도록 보장 (ARC에서 기본 설정) |
| weak | ARC에서 참조를 유지하지 않음 (순환 참조 방지에 사용) |
| assign | 객체가 아닌 기본 타입(int, float, BOOL 등)에 사용 |
| readonly | setter가 없으며 읽기 전용 속성 |
| readwrite | 읽기/쓰기 가능 (기본값) |
| copy | 객체를 복사하여 소유 (ex. NSString 같은 변경 가능한 객체에서 사용) |
automic입니다.(Data race 방지)atomic으로 선언할 경우 안전해 보이긴 하지만, 그만큼 성능 저하가 일어난다.nonatomic을 사용하는 것이 더 효율적입니다.@interface Person : NSObject {
NSString *personName;
NSInteger personAge;
}
- (id)initWithName: (NSString *)name andAge: (NSInteger)age;
- (void)print;
@end
@implementation Person
- (id)initWithName:(NSString *)name andAge:(NSInteger)age {
personName = name;
personAge = age;
return self;
}
- (void)print {
NSLog(@"Nname: %@", personName);
NSLog(@"Age: %ld", personAge);
}
@end
@interface Employee : Person {
NSString *employeeEducation;
}
- (id)initWithName:(NSString *)name andAge:(NSInteger)age andEducation:(NSString *)education;
- (void)print;
@end
@implementation Employee
- (id)initWithName:(NSString *)name andAge:(NSInteger)age andEducation:(NSString *)education {
personName = name;
personAge = age;
employeeEducation = education;
return self;
}
- (void)print {
NSLog(@"Name: %@", personName);
NSLog(@"Age: %ld", personAge);
NSLog(@"Education: %@", employeeEducation);
}
@end
int main(void) {
NSLog(@"Base class Person Object");
Person *person = [[Person alloc]init];
person = [person initWithName:@"han" andAge:29];
[person print];
NSLog(@"Inherited Class Employee Object");
Employee *employee = [[Employee alloc]init];
employee = [employee initWithName:@"lee" andAge:34 andEducation:@"CS"];
[employee print];
}
@interface SampleClass : NSObject {
NSString *name;
}
- (void)setInternalID;
- (NSString *)getExternalID;
@end
@interface SampleClass() {
NSString *internalID;
}
@end
@implementation SampleClass
- (void)setInternalID {
internalID = [NSString stringWithFormat:@"UNIQUEINTERNALKEY%dUNIQUEINTERNALKEY",arc4random()%100];
}
- (NSString *)getExternalID {
return [internalID stringByReplacingOccurrencesOfString:@"UNIQUEINTERNALKEY" withString:@""];
}
@end
int main(void) {
SampleClass *sampleClass = [[SampleClass alloc]init];
[sampleClass setInternalID];
NSLog(@"%@", [sampleClass getExternalID]);
}
@protocol PrintProtocolDelegate <NSObject>
- (void)processCompleted;
@end
@interface PrintClass : NSObject {
id delegate;
}
- (void) printDetails;
- (void) setDelegate: (id)newDelegate;
@end
@implementation PrintClass
- (void)printDetails {
NSLog(@"Printting Details");
[delegate processCompleted];
}
- (void)setDelegate:(id)newDelegate {
delegate = newDelegate;
}
@end
@interface SampleClass : NSObject<PrintProtocolDelegate>
- (void)startAction;
@end
@implementation SampleClass
- (void)startAction {
PrintClass *printClass = PrintClass.new;
[printClass setDelegate:self];
[printClass printDetails];
}
- (void)processCompleted {
NSLog(@"Printing Process Completed");
}
@end
int main(void) {
SampleClass *sampleClass = [[SampleClass alloc]init];
[sampleClass startAction];
}
typedef struct Books {
NSString *title;
NSString *author;
NSString *subject;
int bookID;
} Book;
int main(void) {
Book book;
book.title = @"Objective-C Programming";
book.author = @"han";
book.subject = @"Programming";
book.bookID = 100;
NSLog(@"%@", book.title);
NSLog(@"%@", book.author);
NSLog(@"%@", book.subject);
NSLog(@"%d", book.bookID);
}
define
#define PI 3.14159
int main(void) {
double radius = 5.0;
double area = PI * radius * radius;
NSLog(@"Circle Area: %f", area);
}
const
const double PI = 3.14159;
int main(void) {
double radius = 5.0;
double area = PI * radius * radius;
NSLog(@"Circle Area: %f", area);
}
define은 단순 치환, const는 메모리에 저장| 구분 | #define | const |
|---|---|---|
| 메모리 할당 | 없음 (단순 문자열 치환) | 있음 (메모리에 값 저장) |
| 자료형 존재 여부 | 없음 (타입이 지정되지 않음) | 있음 (명확한 자료형을 가짐) |
| 디버깅 가능 여부 | 어려움 (컴파일 전에 치환됨) | 쉬움 (변수처럼 사용 가능) |
| 스코프(범위) | 전역 (어디서든 사용 가능) | 선언된 블록 내에서만 사용 가능 |
| 상수 값 변경 가능 여부 | 변경 불가능 | 변경 불가능 (const 키워드) |