22-10-07 금요일
4주차
WARNING
⚠️ 경고 ⚠️
이곳은 고대 언어 발굴 현장입니다.
C언어 계열에 알러지가 있으신 분은 특히 주의 바랍니다.
✔️ Objective-C
1️⃣ Functions
objc가 말하는 함수와 swift가 말하는 함수는 다르다.
작업을 함께 수행하는 명령문 그룹
- objc 프로그램에는 main() 함수가 있고, 추가 함수 정의 가능
- 코드를 여러 기능으로 나누는 방법은 마음대로지만, 일반적인 각 기능이 특정 작업을 수행하도록 구분한다.
- 기계적으로는 어떻게든 상관없지만,
- 논리적으로는 하나의 기능을 수행하도록 해야함.
- 함수 선언
- 컴파일러에게 함수 이름, 반환 유형 및 매개변수에 대해 알려줌
- 함수 정의
- 함수의 실제 본문 제공
- 선언, 정의 다르다.
- objc에서 함수를 메서드라고 부름
- C언어에서 함수를 메서드로 부르나? ㄴㄴ objc에서만
잠깐 계보 살펴보기
- obj-c = c + smalltalk(”OOP”)
- C++ = C + “OOP”
- Objective-C++ = C + C++ + obj-c
- objc foundation 프레임워크
- 기본 메서드 제공
- 메소드 → 함수, 서브루틴, 프로시저.. 등의 다양한 이름으로 알려짐
Defining a Method
- (return_type) method_name:( argumentType1 )argumentName1
joiningArgument2:( argumentType2 )argumentName2 ...
joiningArgumentn:( argumentTypen )argumentNamen {
body of the function
}
swift 코드를 Objective-C로 바꿔보자.
func myMethod(myName name: String, myAge age: Int) -> Void { // swift
print("\\(name) \\(age)")
}
myInstance.myMethod(myName: "dadahae", myAge: 13)
- (void)myMethodWithMyName:(NSString*)name myAge: (int)age { // Objective-C
// name 활용
// age 활용
}
[myInstance myMethodWithMyName:@"dadahae", myAge:13]
- 시스템이 바라보는 메소드 이름은 “myMethodWithMyName:myAge:”
- 매개변수는 name과 age
- “myMethodWithMyName:myAge:”(name, age) → 함수의 이름이 되는 것이다.
- Obj-C의 메소드는 함수 호출이라기 보다는 객체와의 메시징을 위한 수단의 성격이 강하다.
#import <Foundation/Foundation.h>
@interface MyNumber: NSObject
- (int)getMaxiumNumberWithFirstNumber:(int)num1 secondNumber:(int)num2;
@end
@implementation MyNumber
- (int)getMaxiumNumberWithFirstNumber:(int)num1 secondNumber:(int)num2 {
int result = num1 > num ? num1 : num2
return result; // call by value
}
@end
int main (int argc, const char * argv[])
{
MyNumber *num = [[MyNumber alloc] init];
int maxNum = [num getMaxiumNumberWithFirstNumber:13 secondNumber:10];
printf("%d", maxNum);
return 0;
}
- 메서드 선언
- 컴파일러에게 함수 이름과 메서드를 호출하는 방법을 알려줌
- 함수 실제 본문은 별도로 정의 가능(implementatation + interface)
Calling a method
- 메소드를 생성하는 동안 함수가 수행해야 하는 작업에 대한 정의 제공
- 프로그램이 함수를 호출하면 프로글매 제어가 호출된 메서드로 전달
- 호출된 메서드는 정의된 작업을 수행
Function Arguments
- 형식 매개변수
- 함수가 인수를 사용하려면 인수 값을 혀용하는 변수를 선언해야 함
- 함수 내부의 다른 지역 변수처럼 작동하고, 함수에 들어갈 때 생성되고 종료할 때 소멸된다.
- 함수를 호출하는 동안 인수를 함수에 전달하는 2가지 방법
- Call by Value
- Call by Reference
#import <Foundation/Foundation.h>
@interface MyNumber: NSObject
- (int)getMaxiumNumberWithFirstNumber:(int)num1 secondNumber:(int)num2;
- (NSString *)getHello;
@end
@implementation MyNumber
- (int)getMaxiumNumberWithFirstNumber:(int)num1 secondNumber:(int)num2 {
int result = num1 > num2 ? num1: num2;
return result; // call by value
}
- (NSString *)getHello {
NSString *hello = @"Hello World";
return hello; // call by reference
}
@end
int main (int argc, const char * argv[])
{
MyNumber *num = [[MyNumber alloc] init];
int maxNum = [num getMaxiumNumberWithFirstNumber:13 secondNumber:20];
NSLog(@"%d", maxNum);
NSString *hello = [num getHello];
NSLog(@"%@", hello);
return 0;
}
Q. result 는 함수 호출이 끝나고 사라질까?
A. ㅇㅇ 사라진다. result는 call by value
Q. hello 는? 함수 호출이 끝나고 사라질까?
A. 포인터로 정의되었기 때문에 살아있답. 주소값으로 접근한다. call by reference
- 값을 복사할건지, 메모리 주소값을 복사할건지~
2️⃣ Blocks
클로저의 조상
- Obj-C 클래스
- 관련 동작, 데이터를 결합하는 개체를 정의함
- 블록
- C, Obj-D, C++에 추가된 기능
- 마치 값인 것 처럼 메서드, 함수에 전달할 수 있는 코드 세그먼트
- NSArray, NSDictionary와 같은 컬렉션에 추가할 수 있음~
- 엔클로징 범위에서 값을 Capture하여 다른 프로그래밍 언어 closure, lambda와 유사
Simple Block declaration syntax
returnType (^blockName)(argumentType);
- 간단한 블록 구현
returnType (^blockName)(argumentType)= ^ {
};
위로 꺽쇠 있다? 아~ 블록이네~
void (^simpleBlock)(void) = ^ {
NSLog(@"This is block");
}
/*
void simpleBlock() {
NSLog(~);
}
로 해도 같은거 아니냐?! 같다. 근데 다른 점은... 값인 것 처럼 할 수 있다 없다의 차이이다.
*/
- 블록 호출
simpleBlock();
멀티스레드
동시성 지원하는 문제 때문에 C언어에서도 적용되었다.
Blocks Take Arguments and Return Values
- 블록은 메서드 및 함수와 마찬가지로
- 인수를 사용하고 값 반환 가능
double (^multiplyTwoValues)(double, double) = // return type, parameter
^(double firstValue, double secondValue) {
return firstValue * secondValue;
};
double result = multiplyTwoValues(2,4);
NSLog(@"The result is %f", result);
3️⃣ Numbers
- Objective-C 프로그래밍 언어에서 int, float, bool과 같은 기본 데이터 유형을 객체 형태로 저장하기 위해, Objective-C는 NSNumber로 작업할 수 있는 다양한 방법을 제공하며 중요한 방법은 다음 표에 나열되어 있습니다.
#import <Foundation/Foundation.h>
// C언어 스타일의 함수
double multiplyTwoValuesOrgin(double firstValue, double secondValue)
{
return firstValue * secondValue;
}
// Block으로 다시 위 함수를 써본다면
// Block의 이름은 (^multiplyTwoValues)(double, double)
// Block의 실제 작동내용은 ^{ ... }으로 구현
double (^multiplyTwoValues)(double, double) = ^(double firstValue, double secondValue){
return firstValue * secondValue;
};
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSLog(@"Hello, World!");
double myNum = multiplyTwoValues(2, 4);
NSLog(@"%f", myNum);
}
return 0;
}
#import <Foundation/Foundation.h>
typedef void (^CompletionBlock)();
@interface SampleClass: NSObject
- (void)performActionWithCompletion:(CompletionBlock)completionBlock;
@end
@implementation SampleClass
- (void)performActionWithCompletion:(CompletionBlock)completionBlock {
NSLog(@"Action performed");
completionBlock();
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"Hello, World!");
SampleClass *sampleClass = [[SampleClass alloc] init];
[sampleClass performActionWithCompletion:^{
NSLog(@"Completion is called to intimate action is performed.");
}];
}
return 0;
}
🦁 11:00 ~ 11:50 잠시 외출!
- 두 숫자를 곱하고 곱을 반환하는 NSNumber를 활용하는 예제
#import <Foundation/Foundation.h>
// Foundation이 제공하는 NSObject를 상속받은 SampleClass는 이러한 내용을 구현합니다.
@interface SampleClass : NSObject
- (NSNumber *)multiplyA:(NSNumber *)a withB:(NSNumber *)b;
@end
// SampleClass의 구체적인 내용은 다음과 같습니다.
@implementation SampleClass
- (NSNumber *)multiplyA:(NSNumber *)a withB:(NSNumber *)b {
// NSNumber 타입으로 받은 a와 b로부터 float 값들을 꺼내서 곱셈한 후
float number1 = [a floatValue];
float number2 = [b floatValue];
float product = number1 * number2;
// 결과를 NSNumber로 다시 만들어 반환한다.
NSNumber *result = [NSNumber numberWithFloat:product];
return result;
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSLog(@"Hello, World!");
// swift였다면 ... var sampleClass: SampleClass = SampleClass()
SampleClass *sampleClass = [[SampleClass alloc] init];
NSNumber *a = [NSNumber numberWithFloat:10.5];
NSNumber *b = [NSNumber numberWithFloat:10.0];
NSNumber *result = [sampleClass multiplyA:a withB:b];
// 결과의 NSNumber로부터 NSString를 만들어 활용한다.
NSString *resultString = [result stringValue];
NSLog(@"The product is %@", resultString);
}
return 0;
}
result의 NSNumber를 NSString으로 만들어 활용도 할 수 있다.
온라인 컴파일러로 돌리면 아래 코드를 참고하세용.
* 오토 릴리즈 코드를 빼고 작성하기!
* Xcode에서는 메모리를 자동으로 관리해주기 때문에 autolease 코드가 존재한다. 자세한건 나중에 배움! (ARC)
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
...
[pool drain];
#import <Foundation/Foundation.h>
// Foundation이 제공하는 NSObject를 상속받은 SampleClass는 이러한 내용을 구현합니다.
@interface SampleClass : NSObject
- (NSNumber *)multiplyA:(NSNumber *)a withB:(NSNumber *)b;
@end
// SampleClass의 구체적인 내용은 다음과 같습니다.
@implementation SampleClass
- (NSNumber *)multiplyA:(NSNumber *)a withB:(NSNumber *)b {
// NSNumber 타입으로 받은 a와 b로부터 float 값들을 꺼내서 곱셈한 후
float number1 = [a floatValue];
float number2 = [b floatValue];
float product = number1 * number2;
// 결과를 NSNumber로 다시 만들어 반환한다.
NSNumber *result = [NSNumber numberWithFloat:product];
return result;
}
@end
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSLog(@"Hello, World!");
// swift였다면 ... var sampleClass: SampleClass = SampleClass()
SampleClass *sampleClass = [[SampleClass alloc] init];
NSNumber *a = [NSNumber numberWithFloat:10.5];
NSNumber *b = [NSNumber numberWithFloat:10.0];
NSNumber *result = [sampleClass multiplyA:a withB:b];
// 결과의 NSNumber로부터 NSString를 만들어 활용한다.
NSString *resultString = [result stringValue];
NSLog(@"The product is %@", resultString);
[pool drain];
return 0;
}
Q. 메소드 헤드부분에는 객체 포인터 타입일때 타입에 괄호()를써주는데 main 함수 내에서 객체 포인터 선언할때에는 괄호()가 없는데 큰차이점이 있나요? 써도되고 안써도되는 부분인가요?
A. main은 C언어 형식의 함수이고, obj-c의 메소드는 자체적인 형식이 따로있다보니 생긴 차이라 볼 수도 있습니다.
(NSNumber *)... 이것은 반환될 타입이 NSNumber의 포인터값이 될거란 뜻이고,
NSNumber *a ... 이것은 a는 NSNumber 타입이 되는 (실제로는 포인터 값이되는) 인스턴스를 뜻한다라는 서로 다른 의미가 되겠습니다.
Q. 그럼 인스턴스 생성할때도 (NSNumber*) a 라고 하면 안되는 부분인가요? 메소드 부분에도 반환될 타입에 괄호가 있지만 a변수 타입 얘기할때에도 똑같이 괄호를 사용해서 붙여준거라 단순히 괄호 유무가 큰 차이를 만드는지 궁금합니다.
A. C언어 포인터 타입 활용 규칙상 NSNumber * a 이렇게 쓰는게 대세이고 국룰이지만, 간혹 Number * a 라고 *를 타입에 붙이는 분들도 계십니다.
Q. 근데 함수 쪽에는 괄호를 다 지워보니 에러가나네요.
A. 네, Obj-C 메소드 문법이 원래 그렇습니다.
Q. multiplyA, withB가 밖에서 메소드 사용할 때 쓰는 이름이고 내부에서는 a 와 b로 사용하는거 맞나요??
A. 네, 공식적인 메소드 이름은 multiplyA:withB: 이고, 메소드 내부에서만 a,b라는 이름을 사용해서 작동됩니다.
Q. 메소드 선언시, 반드시 외부변수명과 내부변수명 모두 작성해야하는지 궁금합니다!
A. 네, 형식이 원래 그렇습니다. 스위프트가 이뻐보이는 이유지요.
Q. 포인터를 왜 써야하는지 잘 모르겠어요.
A. C언어 계열에서는 기본 타입인 int, float 같은 게 아니면 모두 포인터로만 서로 생각해서, 실제 메모리 값은 포인터 주소 찾아가서 살펴보는 형식을 취하는 종특이 있다보니 생긴 일입니다 ㅠㅠ
Q. 그러니까 return 값이나 매개변수로 int float이 아니어서 위 예제에서는 포인터를 사용한 것이라고 이해해도 될까요?
A. 네, 기본 타입 아니면 특히 객체 단위에선 포인터밖에 활용 방법이 없게 되서 그렇지요.
4️⃣ Array
- c
- int a[5] → 0…4
- obj-c
- NSArray → 상수형, 자리 잡히면 못 바꿈
- swift
- struct { mutating func name() { … } }
NSMutableArray 가 mutating의 원조다…
- 고정 크기
- 순서 있음
- 같은 유형의 변수 모음
- 배열의 요소는 인덱스로 접근 가능
- 연속적인 메모리 위치로 구성
- 가장 낮은 주소 → 첫번재 요소
- 가장 높은 주소 → 마지막 요소
Declaring Arrays
- type 지정
- maximum index 지정
type arrayName[arraySize];
이것을 1차원 배열이라고 한다.
- arraySize : 0보다 큰 정수 상수여야 함
- type : 유요한 Obj-C 데이터 유형이 될 수 있음
double balance[10];
Initializing Arrays
- 배열을 하나씩 초기화하거나, 아래와 같이 단일 명령문으로 초기화 가능
double balance[5] = {100.0, 2.0, 3.4, 17.0, 50.0}
- 배열의 크기를 생략하면 초기화한 크기 만큼만 큰 배열이 생성된다.
double balance[] = {100.0, 2.0, 3.4, 17.0, 50.0}
예제)
double balance[] = {100.0, 2.0, 3.4, 17.0, 50.0}
balance[4] = 40.0
- 5번째 요소에 40.0 할당
- 인덱스 4번은 배열의 5번째이다. 0-indexed
Accessing Array Elements
- 배열 이름을 인덱싱하여 요소에 접근함
double salary = balance[9];
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
int myArray[10]; // 10개의 int값이 들어갈 배열 선언
int i, j; // for 반복문에 활용
for (i = 0; i < 10; i++) { // i는 0..<10 구간으로 증가하며 반복
myArray[i] = i + 100;
}
for (j = 0; j < 10; j++) {
NSLog(@"Element[%d] = %d\\n", j, myArray[j]);
}
}
return 0;
}
Arrays in Detail
- NSArray, NSMutableArray
- Obj-C의 배열과 관련된 몇가지 중요한 개념
- 다차원 배열
- 함수에 배열 전달
- 함수에서 배열 반환
- 배열에 대한 포인터
5️⃣ Data Type
- 컴퓨터는 0과 1로만 생각함
- 그래서 2진법 나옴 (이진연산)
- 메모리에 저장할때도 2진법으로 저장, 컴퓨터 메모리에도 0과 1로만 저장된다.
6️⃣ Pointer
Objective-C의 포인터는 배우기 쉽고 재미있습니다.
- 동적 메모리 할당과 같은 작업은 포인터를 사용해야 한다. (아래 코드의 주석내용들 참고)
- 모든 변수는 메모리 위치
- 모든 메모리 위치는 메모리 주소를 나타내는 &(앰퍼센트) 연산자 사용하여 접근.
포인터의 개념을 예시로 이해해보자.
- 포인터 정보 = 해당 데이터의 메모리 주소 + 메모리를 차지하는 크기
- 토지대장 = 주소지(경상북도 울릉군...) + 몇 평수 정보(임야 13평)
주소지 대로 찾아갔는데 정확하게 어디까지의 영역이 내 땅인지 모르면 큰일이다. 메모리 주소도 마찬가지!
코드에서는 타입별 크기대로 주소지에서 영역을 계산한다.
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
int age = 13;
double height = 145.32;
// 변수에 담긴 값을 출력
NSLog(@"value of age : %d", age);
NSLog(@"value of hegith : %f", height);
// 변수가 위치한 메모리 안에서의 주소
NSLog(@"address of age : %x", &age);
NSLog(@"address of height : %x", &height);
// 포인터 정보 = 해당 데이터의 메모리 주소 + 메모리를 차지하는 크기
// 토지대장 = 주소지(경상북도 울릉군...) + 몇 평수 정보(임야 13평)
return 0;
}
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
// 포인터 정보 = 해당 데이터의 메모리 주소 + 메모리를 차지하는 크기
// 토지대장 = 주소지(경상북도 울릉군...) + 몇 평수 정보(임야 13평)
int index = 17;
printf("i stores its value at %x\\n", &index);
printf("this function starts at %x\\n", &main);
return 0;
}
근데 직-접 메모리 주소를 꺼내와서 접근하는건 위험하다. 흠냐링.
- 포인터 변수
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
// 포인터 정보 = 해당 데이터의 메모리 주소 + 메모리를 차지하는 크기
// 토지대장 = 주소지(경상북도 울릉군...) + 몇 평수 정보(임야 13평)
int age = 17;
// 변수 age의 주소를 확인해서, int 타입이 담길 거라고 생각하는 포인터 변수 만들기
int *addressOfAge = &age;
NSLog(@"age는 %p 주소에 위치했습니다.", addressOfAge);
NSLog(@"%p 주소에 가보니 %d 값이 들어있습니다.", addressOfAge, *addressOfAge);
/*
출력문:
age는 0x16fdff3ac 주소에 위치했습니다.
0x16fdff3ac 주소에 가보니 17 값이 들어있습니다.
*/
return 0;
}
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
// 포인터 정보 = 해당 데이터의 메모리 주소 + 메모리를 차지하는 크기
// 토지대장 = 주소지(경상북도 울릉군...) + 몇 평수 정보(임야 13평)
int age = 17;
// 변수 age의 주소를 확인해서, int 타입이 담길 거라고 생각하는 포인터 변수 만들기
int *infoOfAge = &age;
NSLog(@"age는 %p 주소에 위치했습니다.", infoOfAge);
// age는 0x16fdff3ac 주소에 위치했습니다.
NSLog(@"age의 메모리 크기는 %zu 바이트입니다.", sizeof(int));
// age의 메모리 크기는 4 바이트입니다.
NSLog(@"처음 %p 주소에 가보니 %d 값이 들어있습니다.", infoOfAge, *infoOfAge);
// 처음 0x16fdff3ac 주소에 가보니 17 값이 들어있습니다.
*infoOfAge = 32;
NSLog(@"다시 %p 주소에 가보니 %d 값이 들어있습니다.", infoOfAge, *infoOfAge);
// 다시 0x16fdff3ac 주소에 가보니 32 값이 들어있습니다.
NSLog(@"%p를 가르키는 정보의 메모리 크기는 %zu 바이트입니다.", infoOfAge, sizeof(int *));
// 0x16fdff3ac를 가르키는 정보의 메모리 크기는 8 바이트입니다.
return 0;
}
#import <Foundation/Foundation.h>
@interface SampleClass : NSObject
- (void)sayHello;
@end
@implementation SampleClass
- (void)sayHello {
NSLog(@"Hello World");
}
@end
int main(int argc, const char * argv[]) {
// 포인터 정보 = 해당 데이터의 메모리 주소 + 메모리를 차지하는 크기
// 토지대장 = 주소지(경상북도 울릉군...) + 몇 평수 정보(임야 13평)
int age = 17;
// 변수 age의 주소를 확인해서, int 타입이 담길 거라고 생각하는 포인터 변수 만들기
int *infoOfAge = &age;
NSLog(@"age는 %p 주소에 위치했습니다.", infoOfAge);
// age는 0x16fdff3ac 주소에 위치했습니다.
NSLog(@"age의 메모리 크기는 %zu 바이트입니다.", sizeof(int));
// age의 메모리 크기는 4 바이트입니다.
NSLog(@"처음 %p 주소에 가보니 %d 값이 들어있습니다.", infoOfAge, *infoOfAge);
// 처음 0x16fdff3ac 주소에 가보니 17 값이 들어있습니다.
*infoOfAge = 32;
NSLog(@"다시 %p 주소에 가보니 %d 값이 들어있습니다.", infoOfAge, *infoOfAge);
// 다시 0x16fdff3ac 주소에 가보니 32 값이 들어있습니다.
NSLog(@"%p를 가르키는 정보의 메모리 크기는 %zu 바이트입니다.", infoOfAge, sizeof(int *));
// 0x16fdff3ac를 가르키는 정보의 메모리 크기는 8 바이트입니다.
// SampleClass의 인스턴스를 만들어서
// 그 메모리의 위치 정보를 SampleClass클래스에 맞춘 포인터 변수 sampleClass에 할당한다
// 클래스에 의해 만들어지는 인스턴스는 무조건 포인터 단위로 관리해야만 활용 가능하다.
SampleClass *sampleClass = [[SampleClass alloc] init];
// sampleClass 포인터 정보가 가르키는 인스턴스 데이터를 찾아가서
// 데이터에 명시된 sayHello 메소드를 실행하라
[sampleClass sayHello];
return 0;
}
점점 발전하는 중…
#import <Foundation/Foundation.h>
@interface SampleClass : NSObject
- (void)sayHello;
@end
@implementation SampleClass
- (void)sayHello {
NSLog(@"Hello World");
}
@end
int main(int argc, const char * argv[]) {
// 포인터 정보 = 해당 데이터의 메모리 주소 + 메모리를 차지하는 크기
// 토지대장 = 주소지(경상북도 울릉군...) + 몇 평수 정보(임야 13평)
int age = 17;
// 변수 age의 주소를 확인해서, int 타입이 담길 거라고 생각하는 포인터 변수 만들기
int *infoOfAge = &age;
NSLog(@"age는 %p 주소에 위치했습니다.", infoOfAge);
// age는 0x16fdff3ac 주소에 위치했습니다.
NSLog(@"int 타입의 메모리 크기는 %zu 바이트입니다.", sizeof(int));
// int 타입의 메모리 크기는 4 바이트입니다.
NSLog(@"변수 age의 메모리 크기는 %zu 바이트입니다.", sizeof(age));
// 변수 age의 메모리 크기는 4 바이트입니다.
NSLog(@"처음 %p 주소에 가보니 %d 값이 들어있습니다.", infoOfAge, *infoOfAge);
// 처음 0x16fdff3ac 주소에 가보니 17 값이 들어있습니다.
*infoOfAge = 32;
NSLog(@"다시 %p 주소에 가보니 %d 값이 들어있습니다.", infoOfAge, *infoOfAge);
// 다시 0x16fdff3ac 주소에 가보니 32 값이 들어있습니다.
NSLog(@"int를 담은 데이터의 포인터정보 크기는 %zu 바이트입니다.", sizeof(int *));
// int를 담은 데이터의 포인터정보 크기는 8 바이트입니다.
NSLog(@"%p를 가르키는 정보의 메모리 크기는 %zu 바이트입니다.", infoOfAge, sizeof(infoOfAge));
// 0x16fdff3ac를 가르키는 정보의 메모리 크기는 8 바이트입니다.
// SampleClass의 인스턴스를 만들어서
// 그 메모리의 위치 정보를 SampleClass클래스에 맞춘 포인터 변수 sampleClass에 할당한다
// 클래스에 의해 만들어지는 인스턴스는 무조건 포인터 단위로 관리해야만 활용 가능하다.
SampleClass *sampleClass = [[SampleClass alloc] init];
// sampleClass 포인터 정보가 가르키는 인스턴스 데이터를 찾아가서
// 데이터에 명시된 sayHello 메소드를 실행하라
[sampleClass sayHello];
return 0;
}
What Are Pointers?
그 값이 다른 변수의 주소, 즉 메모리의 위치~
int *ip // pointer to an integer
double *dp // pointer to a double
float *fp // pointer to a float
char *ch // pointer to a character
- 정수, 부동소수점, 문자 등 모든 포인터 값의 실제 데이터 유형은 메모리 주소를 나ㅏ내는 긴 16진수로 동일합니다.
- 다른 데이터 유형의 포인터 간의 유일한 차이점은 포ㅇ잉..(응애-)
How to use Pointers?
- 포인터 변수 정의
- 변수의 주소를 포인터에 할당
- 포인터 변수에서 사용가능한 주소의 값에 접근한다.
NULL Pointers
- 할당할 정확한 주소가 없는 경우 포인터 변수에 NULL 값을 할당.
- NULL 포인터는 여러 표준 라이브러리에서 0이라고 약속함.
7️⃣ String
- NSString으로 문자열 표현
- NSString의 하위 클래스 NSMutableString은 문자열 개체를 생성하는 여러 방법 제공
- 문자열 개체를 만드는 가장 간단한 방법
- @” … “
NSString *greeting = @"Hello"
예시)
#import <Foundation/Foundation.h>
int main() {
NSSting *greeting = @"Hello";
NSLog(@"Greeting message: %@\\n", greeting);
return 0;
}
✔️ Xcode 둘러보기
간단하게 Xcode를 둘러보면서 프로젝트 만드는 방법을 배웠다. (와! Xcode!)
이 부분은 기록하기 보다는 완전 가볍게 보여주셔서 나도 듣고 감상하는 느낌으로 들었다.
CocoaPods
- cocoa?
- 애플이 넥스트사를 인수하고 나서 뷰를 그리는 방법들을 소개로 할 때 기본적인 프로젝트 이름을 ‘coco’라고 했다.
- 아이폰, 맥용 단위로 프로젝트를 만들면 기본 이름이 cocoa touch…
- Cocoapods은 Ruby로 만들었다.
- 주로 Objective-C코드로 되어 있는게 이곳에 많이 남아있다.
Swift Package Manager
애플에서 이제 직접 종속성 관리를 지원한다! 나도 코코아팟은 처음 써봤다. 거의 SPM으로 했지.. 완전 편하다.
'외부활동 > 멋사 앱스쿨 1기' 카테고리의 다른 글
[TIL] 22-10-12: Objective-C (Protocol, ARC, binding) (0) | 2022.10.16 |
---|---|
[TIL] 22-10-11: Objective-C (struct, typedef, class, extension) (0) | 2022.10.12 |
[TIL] 22-10-06: Objective-C 기본 지식 (0) | 2022.10.06 |
[TIL] 22-10-05: Swift (Closure), Objective-C (0) | 2022.10.06 |
[TIL] 22-10-04: Swift(Error Handling, Type, Property Observer, enum, Generic, Protocol Oriented) (2) | 2022.10.06 |