Starbucks Caramel Frappuccino
본문 바로가기
  • 그래 그렇게 조금씩
iOS Developer/Objective-C

7. Objective-C 함수(call by value, call by reference)

by Toughie 2024. 5. 6.

KAKAO-Choonsik

함수는 작업을 수행하기 위한 여러 문장의 모음이라고 할 수 있다. 

프로그램의 시작점인 main()함수를 비롯해, 추가적인 함수를 필요에 따라 정의할 수 있다.

재사용성, 모듈화 등등 함수와 관련된 기법보다는 정말 기본 개념을 알아보자. 이건 정말 그냥 코드 짜면서 해봐야 느는듯..


함수 선언(Declaration)

컴파일러에게 함수의 이름, 반환타입, 파라미터에 대한 정보를 전달한다.

int add(int num1, int num2); //전방 선언

~~~~

//함수 구현
int add(int num1, int num2) {
    return (num1 + num2);
}

함수 정의(Definition)

함수의 body 파트를 구현하는 것을 의미한다.

 

기본적으로 옵젝씨에서는 함수를 메서드라고 부르고,

문자열에 문자열을 더하는 appendString()과 같은 다양한 내장 메서드도 존재한다.

 

* NSString은 불변 타입으로 한 번 생성된 객체의 내용을 변경하는 것은 불가능하다.

아예 새로운 객체를 만들어서 변수에 할당하는 것은 가능하다.

따라서 NString의 내장 메서드인 stringByAppendingString을 사용해서 새로운 객체를 만들거나,

아래와 같이 NSMutableString의 내장 메서드인 appendingString을 활용할 수 있다.

 

NSMutableString *mutableString = [NSMutableString stringWithString:@"mutable!"];
[mutableString appendString: @"APPEND"]; //객체 메서드 호출 - 메세지를 보낸다고 한다. 대괄호 사용
NSLog(@"%@",mutableString);

 

역시 c계열은 문자열이 참 까다롭다..


함수의 구조

- (return_type) method_name:( argumentType1 )argumentName1 
joiningArgument2:( argumentType2 )argumentName2 ... {
   body of the function
}

 

*함수 정의에서는 parameter(인자,매개변수)로, 함수 호출시에는 argument(인수)라고 하는데 혼란이 없길..

 

(-, +) : -는 인스턴스 메서드임을, +는 클래스 메서드(static)를 의미한다.

return type :  값을 반환하지 않는 경우는 void, 그 이외에는 반환값의 타입을 적어준다.

method_name : 파라미터와 함께 메서드 시그니처를 구성하며, 이걸로 호출한다.

 

arguments - 0개 이상의 인수를 전달할 수 있다. 

joiningArgument - 인수의 플레이스홀더로 어떤 인수인지 설명(가독성 증가)

첫 번째 인수에는 joiningArgument를 사용하지 않는데, 이는 메서드 이름을 통해 유추가 가능하기 때문이라고 한다.

 

주로 joiningArgument와 :을 통해서 파라미터를 구분하는데, 파라미터의 이름이 없는 경우 그냥 콤마,로도 구별할 수 있다.

이게 익숙한데..

위 개념이 발전해서 Swift에서 argument label로 바뀐 것 같다.

//Swift argument label
func greet(name: String, message: String) {
    print("\(message), \(name)");
}

 

메서드 선언, 정의, 사용 예시

#import <Foundation/Foundation.h>

@interface MyClass: NSObject
 -(int) max: (int) num1 secondNumber: (int) num2;
@end

@implementation MyClass

-(int) max: (int) num1 secondNumber:(int)num2 {
    if(num1 > num2) {
        return num1;
    } else {
        return num2;
    }
}

@end
int main(void) {
    
    MyClass *myClass = [[MyClass alloc] init];
    int result = [myClass max:7 secondNumber:3];
    NSLog(@"%d",result);
}

함수의 호출 (Call)

함수를 호출하면, 프로그램 제어권이 호출된 메서드의 컨텍스트로 이전된다.

호출된 메서드의 작업이 끝나고 return되면 제어권을 다시 반환한다. (반환값이 있다면 값과)

call by value vs call by reference

함수의 형식 파라미터의 종류에 따라 호출 방식이 달라진다. (값이냐? 메모리 주소냐?)

파라미터 또한 함수 스코프 내부에서 지역 변수처럼 동작하는데, 기본적으로 objective-C에서는 call by value 방식으로 동작한다.

 

쉽게 말하자면 일반적인 값들은 복사돼서 전달되고, 내부에서 사용되기 때문에 원본에 변화가 없고,

객체와 같은 참조 타입은 메모리 주소가 복사돼서 전달되기 때문에 객체를 참조하면서 원본에 변화가 있을 수 있음을 유의해야 한다.

 

#import <Foundation/Foundation.h>

@interface SwapClass : NSObject
- (void) swap: (int) num1 num2: (int) num2;
- (void) swapOrginal: (int*) num1 num2: (int*) num2;
@end

@implementation SwapClass

//복사돼서 값이 전달되기에 원본이 변하지 않는 call by value
- (void) swap: (int) num1 num2: (int) num2 {
    int tmp = num1;
    num1 = num2;
    num2 = tmp;
}

//포인터를 통해 원본의 값을 변경하는 call by reference
- (void) swapOrginal: (int*) num1 num2: (int*) num2 {
    int tmp = *num1;
    *num1 = *num2;
    *num2 = tmp;
}

@end

int main(void) {
    int a = 1;
    int b = 10;
    SwapClass *swapClass = [[SwapClass alloc] init];
    [swapClass swap:a num2:b];
    NSLog(@"a: %i, b: %i",a,b); //a: 1, b: 10
    
    //& 주소연산자 사용
    [swapClass swapOrginal:&a num2:&b]; //a: 10, b: 1
    NSLog(@"a: %i, b: %i",a,b);
    
    return 0;
}

 

포인터 윽.. ㅋㅋㅋ🙄

Objective-C도 malloc, free, 이중 포인터 그냥 다 있더라.. 그냥 애플 스킨만 낀 C 그 자체..superset...

'iOS Developer > Objective-C' 카테고리의 다른 글

9. Objective-C NSNumbers  (0) 2024.05.07
8. Objective-C Blocks 블록  (0) 2024.05.07
6. Objective-C 반복문/조건문  (0) 2024.05.06
4. Objective-C 변수/상수  (0) 2024.05.06
3. Objective-C 자료형  (0) 2024.05.05