CLOSE SEARCH
POSTS TAGGED WITH: iOS

컬렉션 뷰(UICollectionView) #4. 편집 메뉴 추가!

Long-Tap Gesture & Edit menu

collection_edit_menu

컬렉션 뷰 셀을 길게 터치하면 셀 위쪽에 셀에 대한 편집 메뉴가 표시됩니다. 이 편집 메뉴를 통해 자르기, 복사, 붙여넣기 기능을 직접 구현할 수 있습니다. 컬렉션 뷰는 화면에 편집 메뉴를 표시해주는 역할을 할 뿐, 실제 내부 구현은 모두 직접 구현해야 합니다.

배열을 초기화할 때 EXC_BAD_ACCESS 오류가 발생한다면?

다음 코드를 사용해서 배열을 초기화하면 에러가 발생합니다.

이유가 무엇일까요?

“Movies”에 해답이 있습니다.

NSArray에 추가할 수 있는 것은 Objective-C 객체로 한정됩니다. 그런데 “Movies”는 char*(또는 const char*)로 표현되는 C 문자열입니다. 문자열 앞에 @을 붙여 Objective-C 문자열 객체로 만들어 주어야 정상적으로 동작합니다.

막상 이런 오류를 만나면 문자열 앞에 @이 빠졌다는 것을 발견하기가 의외로 어렵습니다. 프로그램이 배열을 초기화하는 위치에서 오류를 발생시킨다면 @이 빠진 문자열은 없는지, 올바른 객체를 추가했는지 확인해 본다면 오류 해결!!

Automatic Reference Counting (ARC)

Automatic Reference Counting (ARC) 는 컴파일 시에 자동으로 적절한 위치에 retain, release, autorelease와 같은 메모리 관리와 관련된 메소드를 추가해 가비지 컬렉터와 유사하는 기능을 제공하는 기술이다.

ARC는 Mac OS X v10.6과 v10.7용 xCode 4.2 이상에서 개발할 수 있으며 iOS4와 iOS5에서 지원된다. 약한 참조(weak reference)의 경우 iOS5이상에서만 지원된다.

ARC를 사용하기 위해 아래와 같은 규칙을 따라야한다.

  • retain, release, retainCount, autorelease, dealloc을 명시적으로 호출하거나 구현할 수 없다. 특히 dealloc 메소드를 구현하는 경우 상위 클래스 호출은 컴파일러에서 수행하기 때문에 [super dealloc]를 호출할 필요가 없으며, 실제로 이 코드는 컴파일 에러를 발생시킨다.
  • alloc: 를 사용해서 객체를 생성한다. 객체의 해제는 런타임이 담당한다.
  • C 구조체 내부에서 객체 포인터를 사용할 수 없다. 대신 클래스를 사용한다.
  • id와 void* 를 암시적으로 형변환 해주지 않는다.  컴파일러에게 객체의 수명에 대해 알려주는 특별한 형변환을 사용해야 한다.
  • NSAutorelease 객체를 사용할 수 없다. 대신 더 효율적인 @autoreleasepool 블록을 사용한다.
  • 더 이상 메모리 존을 사용할 수 없으며, 사용한다고 하더라고 런타임에 의해 무시된다.
  • ARC를 사용하지 않는 이전 코드와 함께 사용할 경우 new로 시작하는 속성명을 사용할 수 없다.
ARC에는 객체의 수명을 지정하는 몇가지 새로운 lifetime qualifier와 zeroing weak reference를 제공한다. 약한 참조는 대상 객체의 수명에 영향을 주지 않지만, zeroing weak reference는 대상 객체가 해제되면 자동으로 nil값을 가지게 된다.
ARC는 이전 참조 카운팅 방식에서 발생하던 strong reference cycles(retain cycle) 문제를 방지해주지 않으므로 신중하게 사용해야 한다.
@property의 속성에 새로운 strong, weak 키워드를 사용할 수 있다. 참조카운팅 방식에서 사용하던 아래의 코드는

ARC를 사용해서 아래와 같이 작성한다.

또한, 아래의 코드는

아래와 같이 작성한다.

assign을 사용하는 경우 myObject의 대상 객체가 해제되면 댕글링 포인터가 되지만, weak의 경우 nil로 설정된다.(zeroing weak reference)

 

ARC는 아래와 같은 새로운 Variable Qualifier를 제공한다.

  • __strong  : 기본값
  • __weak : zeroing weak reference. 대상 객체가 해제되면 nil이 됨.
  • __unsafe_unretained : weak reference. 대상 객체가 해제되면 댕글링 포인터가 됨.
  • __autoreleasing : id* 형식의 인수가 리턴시에 자동적으로 해제되도록 지정.
함수 내부에서 __weak를 사용할 경우 해당 객체의 유효성에 주의해야 한다.

위의 코드를 xCode에서 입력해보면 “Assigning retained object to weak variable; object will be released after assignment” 경고가 발생한다. weak 변수에 retain된 객체를 할당하게 되면 해당 객체가 할당된 후에 해제된다는 것이다. 실제로 위의 코드에서 alloc로 생성한 NSString 객체는 string에 할당된 직후에 해제되므로 2번 라인에서는 string : (null)이 출력된다.

 

ARC는 새로운 방식으로 Autorelease Pool을 사용한다. 참조 카운팅 방식에서와 같이 NSAutoReleasePool 객체를 직접 사용할 수는 없다.

 

아웃렛을 선언하는 방식 역시 ARC를 사용하는 방식에 맞게 변경되었다. File’s Owner와 nil 파일의 최상위 객체들은 strong, 그 외의 객체들은 weak 가 되어야 한다.

ARC를 사용하는 경우 strong, weak, autoreleasing 스택 변수들은 자동적으로 nil로 초기화 된다.

ARC를 활성화 하기 위해서는 -fobjc-arc 컴파일러 플래그를 사용한다. 프로젝트에서 ARC를 기본적으로 사용하는 경우 특정 파일에 대해 참조 카운팅 방식을 사용할 수도 있는데 해당파일에 -fno-objc-arc 플래그를 사용하면 된다.

위치, 방향 그리고 CoreLocation

CoreLocation 프레임워크는 현재 위치에 대한 정보를 제공해준다. 그 중에서도 중요한 역활을 하는 CLLocationManager 클래스는 iOS 2.0 이상의 디바이스에서 현재 위치와 방향에 대한 이벤트를 제공하고 관련 작업을 지원해 주는 클래스이다. 주요 기능들을 살펴보면

  • 정확도를 지정하여 사용자의 현재 위치 변화를 추적할 수 있다.
  • 디바이스에 내장된 나침반을 통해 방향의 변화를 감지하고 해당 정보를 얻어올 수 있다.
  • 사용자가 특정 지역으로 들어가거나 나오는 상황을 감지할 수 있다.

일부 정보의 경우 디바이스에 해당 정보를 얻거나 감시하는데 필요한 하드웨어를 내장하고 있어야 하며, CLLocationManager 클래스에서 이를 확인하는 메소드들을 제공하고 있다. 또한 이들 하드웨어는 전력을 많이 소비하므로 반드시 필요한 경우에만 활성화시켜야 한다.

  1. CLLocationManager를 이용하는 일반적인 순서는 아래와 같다.
  2. 해당 기능을 사용하기 전에 디바이스 지원 여부와 CLLocationManager 클래스에서 제공하는 메소드를 통해 해당 기능 사용 가능여부를 확인하고, 사용이 불가한 경우 작업을 취소한다.
  3. CLLocationMananger 클래스의 인스턴스를 생성한다.
  4. 델리게이트(CLLocationManagerDelegate)를 설정한다.
  5. 사용하고자 하는 기능과 관련된 속성들을 설정한다.
  6. 해당 기능과 관련된 시작 메소드를 호출하여 이벤트를 수신한다.

가속도계 / Accelerometer

iOS기반 디바이스에 내장된 가속도계에 접근하기 위해서는 UIAccelerometer 클래스를 통해 제공되는 공유 인스턴스를 이용한다. + (UIAccelerometer *)sharedAccelerometer 메소드를 통해 가속도계의 공유 인스턴스를 얻은 다음 업데이트 주기와 델리게이트를 설정하면 가속도계 변경 이벤트를 받을 수 있다. 설정 가능한 최대 주기값은 디바이스의 성능에 따라 다르지만 일반적인 앱에서는 1/10, 게임에서는 1/60 정도가 적당하다. 가속도계 사용을 마친 후에는 델리게이트를 nil로 설정한다.

 

UIAccelerometerDelegate

UIAcceleration 클래스는 가장 최근에 발생한 가속도 이벤트에 대한 정보(x, y, z, timestamp)를 가지고 있는 클래스이다. 각 축은 해당 방향으로의 중력 가속도를 나타내며 1.0은 중력가속도 1.0g를 의미한다.

Orientation of the device axes from iOS Developer Library