콘텐츠로 건너뛰기
Home » Development » Objective-C » Page 7

Objective-C

iOS 앱의 구조

아이폰 앱 강좌를 검색하다보면 IB없이 만들기와 관련된 강좌가 상당히 많다. 즉 인터페이스 빌더 없이 모든 UI를 코드로 제어하는 형태로 앱을 개발하는 방법이다. 초보자에게는 추천하기 어렵고 또한 이렇게 코드로 UI를 구성하면 준비해야 하는 코드가 상당히 많아지는데, nib 파일로부터 객체가 생성되는 부분 특히 이렇게 어디선가 갑자기 툭 튀어나오는 객체들을 어떻게 처리해야 할지에 대해서는 좀 난감한 부분들이 있다보니 nib 파일을 사용하지 않는 방식으로 개발을 많이 하고 있는 것 같다.

그래서 오늘은 iOS앱의 구조에 대해 잠시 살펴보도록 하겠다. 분명 IB, 즉 nib 파일을 사용하는 방식은 빠른 시간안에 UI 레이아웃을 구성하고 시각적으로 조정하므로 별도의 컴파일없이 시각적으로 결과물을 확인할 수 있다는 점에서 장점을 가진다. nib 파일에 대한 이해가 어느 정도 충족된다면 인터페이스 빌더를 사용하여 앱을 개발하는 것이 그다지 나쁜 것만은 아님을 알 수 있을 것이다.

더 보기 »iOS 앱의 구조

[Cocoa] Pasteboard를 사용하여 복사/붙여넣기

페이스트 보드 사용하기

임의의 클래스를 페이스트 보드로 복사하고 또 읽어와서 붙여넣기를 하려면 객체의 데이터를 직렬화된 데이터나 프로퍼티 리스트로 변경할 수 있어야 한다. 따라서 이 글을 읽기 전에 이와 관련된 문서들을 먼저 읽을 것을 권한다.

페이스트 보드

복사/붙여넣기를 하면 컴퓨터 메모리의 특정한 영역에 해당 데이터를 복사해두고 필요시에 (심지어는 다른 애플리케이션에서도) 이 데이터를 언제든 꺼내어 쓸 수 있다. 이 영역은 페이스트보드 서버에 의해 관리되는데, 코코아 앱에서는 NSPasteboard 객체를 통해 이 서버의 서비스에 접근할 수 있다. 페이스트 보드는 단순히 복사/붙여넣기 작업에만 관련되지 않고 드래그앤드롭이나 시스템 서비스 호출 시 데이터를 넘겨주는 데에 사용될 수 있는데, 이를 위해 페이스트 보드 서버는 몇 가지 종류의 페이스트 보드를 마련해두고 있으며, 일반적으로 많이 쓰이는 페이스트 보드에 대해서는 고유한 이름이 붙어 있다.

더 보기 »[Cocoa] Pasteboard를 사용하여 복사/붙여넣기

[Objective-C] 메소드를 동적으로 추가하기

보통 객체에 필요한 메소드는 해당 객체의 클래스에서 미리 정의된다. 그러나 경우에 따라서는 객체에 동적으로 메소드를 추가해야 하는 경우가 있다. (도대체 언제?) 실행 시간에 동적으로 메소드를 추가하는 경우는 상상하기 어려운데, 코어 데이터를 사용할 때 자동으로 생성되는 모델 클래스에서 볼 수 있는 @dynamic 지시어가 붙은 프로퍼티 선언이 여기에 해당한다고 볼 수 있다.

더 보기 »[Objective-C] 메소드를 동적으로 추가하기

[Objective-C] 메시지로부터 메소드가 호출되는 과정

objc_msgSend 함수와 메시징 매커니즘

objective-c에서는 객체의 메소드를 호출하는 것을 객체에게 메시지를 보낸다라고 표현한다. 이는 메소드 자체를 객체화하는 디자인 패턴과 쉽게 익숙해질 수 있게 하려는 포석이기보다는 실제로 메소드의 호출이 메시지를 보내는 형태로 구현이 되어있기 때문이다. objective-c의 이러한 메시징 매커니즘을 이해하려면 몇 가지 깊숙한 곳의 내용을 찬찬히 들여다 볼 필요가 있다.

더 보기 »[Objective-C] 메시지로부터 메소드가 호출되는 과정

[c/objetive-c] 불투명 타입

불투명타입(Opaque Type)

코어 파운데이션 관련 문서를 보면 불투명타입(Opaque Type)이라는 말이 자주 나온다. 코어 파운데이션에서 객체처럼 사용되는 모든 타입들은 불투명타입(CFArrayRef, CFStringRef 등등)이다. "불투명"하다고 해서 감이 쉽게 오지 않는데, 간단히 풀어 쓰자면 "내부의 데이터 구조를 들여다볼 수 없는 타입"이라고 보면 된다.

코코아에서 객체를 만들 때 인스턴스 변수는 기본적으로 protected 나 private으로 만들어지기 때문에 이러한 인스턴스 변수는 객체가 이를 읽거나 쓸 수 있는 메소드(accessor)를 제공하지 않는 이상 객체 속에 어떤 변수들이 있는지 외부에서는 알 수 없다.

더 보기 »[c/objetive-c] 불투명 타입

macOS의 메모리 관련 설명

메모리 성능 관리 지침

도입

메모리는 모든 프로그램이 사용하는 중요한 시스템 자원이다. 프로그램은 실행되기 전에 반드시 메모리로 로드되어야 하고, 실행되는 동안에는 명시적으로나 묵시적으로 추가적인 메모리를 할당받아 프로그램에서 사용하는 정보를 담고, 조작할 수 있게 한다. 프로그램의 코드와 데이터를 위한 메모리상의 공간을 만드는 작업은 시간과 비용이 드는 일이며, 따라서 이러한 작업은 시스템의 전체 성능에 영향을 끼친다. 메모리를 많이 사용하는 일을 피하기는 어렵지만, 메모리 사용으로 시스템에 다른 부분에 영향을 끼치는 일은 최소화하는 몇 가지 방법은 있다.

더 보기 »macOS의 메모리 관련 설명

[Objective-C] NSInvocation 과 Forward

코코아 앱의 Undo/Redo 기능을 구현하는 부분을 보면, NSUndoManager-prepareWithInvocationTarget: 메소드를 사용해서 Undo 동작시에 호출될 메소드를 기록해두는 코드가 있다. 그런데 이 메소드의 원형을 보면 좀 이상한 부분이 있다. 실제로 Undo를 지원하는 기능을 구현하고 있는 간단한 코드를 보자.

-(void) getHigher {
    // undo 관리자에 실행취소를 위한 동작을 등록
    [[undoManager prepareWithInvocationTarget:self] getLower];  
    self.height -= 1.0;
}

-(void) getLower {
    [[undoManager prepareWithInvocationTarget:self] getHigher];
    self.height += 1.0;
}

-prepareWithIvocationTarget: 메소드는 자기자신, 즉 NSUndoManager의 인스턴스를 리턴한다. 그런데 이 되돌리기 관리자에게 getLower 를 호출한다?

더 보기 »[Objective-C] NSInvocation 과 Forward

(C/Objc) 함수 포인터와 코드 블럭

C언어에서 어떤 타입의 배열과 포인터는 다른 것이지만, 흔히들 혼용해서 사용하기도 한다. 이것은 배열의 이름 그자체가 배열의 시작번지를 나타내는 값으로 작동하기 때문이다. 그런데 함수에 대해서도 이와 비슷한 규칙이 성립한다. 프로그램이 실행되는 동안, 프로그램 내의 모든 실행코드들은 메모리에 올라와 있다. 이 말은 즉, 함수가 실행되기 위해서는 해당 함수의 실행코드가 메모리 상에 로드되어 있다는 말이고, 함수의 시작번지를 프로그램은 어떤식으로든 알고 있다는 것이다. 배열의 예와 마찬가지로 함수의 이름은 함수의 실행코드가 로드되어 있는 메모리 주소를 가리킨다. 그렇다면 임의의 T타입 배열의 이름을 T타입 포인터에 대입해서 그… 더 보기 »(C/Objc) 함수 포인터와 코드 블럭

[Cocoa] 키밸류 코딩 – 집합 연산

Key-Value 코딩에서 특정한 프로퍼티를 가리키는 키패스의 요소 중에 배열이나 집합(NSSet)과 같은 컬렉션 컨테이너가 있다면, 해당 집합에 대한 개수, 합계, 평균등의 집합 연산을 수행한 결과를 얻도록 하는 키패스 연산자가 있다. 잘 활용하면 코딩의 양을 많이 줄일 수 있다.

키패스는 키 이름을 “.“을 사용해서 연결하는데, 집합 형태의 객체를 가리키는 이름 뒤에 @ 으로 시작하는 연산 종류를 언급하고 다시 뒤에 계산할 속성을 지정할 수 있다. 예를 들어서 “students.@avg.mathScore“와 같이 표기하면 students 라는 배열의 각 요소들에 대해서 mathScore 속성을 취한 후 이를 평균한 값을 얻게 된다. 원소의 개수를 세는 .@count 는 우항 연산자가 없다. “students.@count“는 집합 students의 원소의 개수를 지칭한다.

더 보기 »[Cocoa] 키밸류 코딩 – 집합 연산

[Cocoa] NSArray 정렬하기

Swft의 Array는 간단한 방법으로 정렬할 수 있지만, Objecitve-C의 배열인 NSArray는 정렬하는 것이 그리 간단치가 않다. 배열을 정렬하기 위해서는 어떤 알고리듬을 사용하는지와 무관하게 기본적으로 두 개의 요소 중에서 어느 것이 앞으로 가야할지, 비교할 수 있는 기준이 필요하다. 두 요소가 특정 기준에 대해 동일한 값을 같는다면 두 번째로 적용되어야 할 기준을 사용하는 경우도 있다.

더 보기 »[Cocoa] NSArray 정렬하기