Objective-C Runtime Programming Guide 요약 자료입니다.
Objective-C 런타임을 사용하면 성능을 향상 시킬수 있는 기법을 사용할 수 있습니다.
동적 바인딩이 속도면에서는 접고 들어가는거라 런타임 기능을 이해하면 좀 더 향상된 앱을 개발할 수 있지 않을까 합니다~~
일부 다른 자료 참고했고, 이미지도 이모씨!!의 자료 사용했습니다~ㅋ
자바에서 모델객체를 생성할 때 setter/getter/toString/hashCode/equals 메소드를 만드는데 이럴 경우 클래스 파일의 소스가 길어지고 복잡해지는데 이를 해결하기 위해 롬복(Lombok)을 사용한다.
클래스 안에 있는 필드에 대해 Getter, Setter의 생성이나, toString(), equals(), hashCode() 메서드, 생성자를 자동으로 생성 해준다.
설치
http://projectlombok.org/download.html 에서 jar 파일을 다운로드 후 실행(더블클릭해서 실행 안되면 javaw –jar lombok.jar로 실행하자)
maven의 설정 파일에 의존성 추가
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.6</version></dependency>
Gradle의 설정 파일에 의존성 추가
Compile('org.projectlombok:lombok:1.16.6')
스프링 부트를 사용한다면 프로젝트 생성시 두번째 화면에서 Core -> Lombok을 선택하면 자동으로 라이브러리가 추가된다.
어노테이션
@Getter : Getter 메소드를 생성해 준다.
@Setter : Setter 메소드를 생성해 준다.
getter 는 필드값을 리턴하며 필드명이 name 일때 게터 메소드 이름은 getName (name이 boolean 일때는 isName), 기본 setter는 filed 명이 name 일때 setName이 된다. return type은 void 이며 field 와 동일한 type의 라파미터를 한 개만 입력받는다. 생성된 getter/setter method 의 기본 접근레벨은 AccessLevel 키워드를 명시적으로 지정하지 않았다면 public 이며 Accesslevels 은 PUBLIC, PROTECTED, PACKAGE, and PRIVATE 중에 설정할 수 있다.
자바에서 모델객체를 생성할 때 setter/getter/toString/hashCode/equals 메소드를 만드는데 이럴 경우 클래스 파일의 소스가 길어지고 복잡해지는데 이를 해결하기 위해 롬복(Lombok)을 사용한다.
클래스 안에 있는 필드에 대해 Getter, Setter의 생성이나, toString(), equals(), hashCode() 메서드, 생성자를 자동으로 생성 해준다.
설치
http://projectlombok.org/download.html 에서 jar 파일을 다운로드 후 실행(더블클릭해서 실행 안되면 javaw –jar lombok.jar로 실행하자)
maven의 설정 파일에 의존성 추가
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.6</version></dependency>
Gradle의 설정 파일에 의존성 추가
Compile('org.projectlombok:lombok:1.16.6')
스프링 부트를 사용한다면 프로젝트 생성시 두번째 화면에서 Core -> Lombok을 선택하면 자동으로 라이브러리가 추가된다.
어노테이션
@Getter : Getter 메소드를 생성해 준다.
@Setter : Setter 메소드를 생성해 준다.
getter 는 필드값을 리턴하며 필드명이 name 일때 게터 메소드 이름은 getName (name이 boolean 일때는 isName), 기본 setter는 filed 명이 name 일때 setName이 된다. return type은 void 이며 field 와 동일한 type의 라파미터를 한 개만 입력받는다. 생성된 getter/setter method 의 기본 접근레벨은 AccessLevel 키워드를 명시적으로 지정하지 않았다면 public 이며 Accesslevels 은 PUBLIC, PROTECTED, PACKAGE, and PRIVATE 중에 설정할 수 있다.
부동산앱을 사용하는 비율은 30대가 가장 높고, 상대적으로 남성이 많았습니다.
3개의 앱의 연령별 비교를 살펴보면 10~20대는 직방을, 30~40대는 네이버 부동산을 많이 사용하는 것이 가장 큰 특징입니다.
특히, 연관키워드를 살펴보면 상대적으로 높은 연령대가 사용하는 네이버 부동산은 '분양', '아파트'가 직방, 다방은 '원룸','오피스텔', '투룸'이 주된 키워드였습니다.
이는 연령대별로 선호하는 관심사에 따라 사용하는 부동산앱이 다르다는 것을 볼 수 있습니다.
부동산앱을 사용하는 비율은 30대가 가장 높고, 상대적으로 남성이 많았습니다.
3개의 앱의 연령별 비교를 살펴보면 10~20대는 직방을, 30~40대는 네이버 부동산을 많이 사용하는 것이 가장 큰 특징입니다.
특히, 연관키워드를 살펴보면 상대적으로 높은 연령대가 사용하는 네이버 부동산은 '분양', '아파트'가 직방, 다방은 '원룸','오피스텔', '투룸'이 주된 키워드였습니다.
이는 연령대별로 선호하는 관심사에 따라 사용하는 부동산앱이 다르다는 것을 볼 수 있습니다.
음악앱을 사용하는 연령대는 20대가 가장 높은 것으로 나타났습니다.
개별앱 사용자 비율을 보았을때 멜론을 사용하는 비율이 압도적으로 높고, 나머지는 지니 뮤직, 엠넷이 차지하였습니다.
또한, 음악앱은 다른 앱과는 달리 평균 사용횟수가 높고 평균 사용시간 역시 많았는데요~
이는 사용자들이 음악앱을 자주, 그리고 오랫동안 사용한다는 것을 알 수 있었습니다.
*** 소개팅 앱 3종 비교분석 ***
소개팅 앱을 사용하는 연령대는 20~30대 남성이 압도적으로 많았습니다.
여기서 중요한건 남성이 압도적!!
또한, 개별앱 사용자의 비율은 3개의 앱의 사용율이 대체적으로 비슷하게 나왔는데요~
평균 사용횟수가 높은 앱은 너랑나랑, 아만다, 정오의 데이트 순으로 나타났습니다.
앞으로 경쟁앱과의 차별화된 전략이 필요한 시점이지 않을까요~
2015년 하반기 출시 예정인 새로운 기능을 포함한 UBhina Analytics 서비스 소개서 입니다.
앱 사용에 대한 트렌드 분석, 앱 사용 분석, 장애 분석 이 모든 것이 가능한 통합 모바일 데이터 분석 서비스를 제공합니다.
앱 개발, 모바일 서비스를 운영중인 기업에게 꼭 필요한 다양한 통계 기능을 제공합니다.
UBhind Analytics - 여행 및 지역정보 앱 사용성 분석 리포트 입니다.
- 여행 및 지역정보 앱 사용 현황
- 여행 및 지역정보 카테고리 이용 특성 : Top 100
- 여행 및 지역정보 카테고리 이용 특성 : 앱 - 성별 Top 10
- 여행 및 지역정보 카테고리 이용 특성 : 앱 - 연령 Top 10
- 여행 가이드앱 비교
- 숙박앱 비교
- 지도앱 비교
- 교통앱 비교
자세한 정보는 ubhind.com 회원 가입 후 보실 수 있습니다.
[UBhind Analytics] 2015 6월 3,4주 주요지표 리포트Sung-Kwan Kim
UBhind Analytics 6월 두번째 주요 지표 리포트 입니다.
분석기간 : 2015년 6월 16일 ~ 30일
1. 하루평균 스마트폰 사용시간(전체, 성별, 연령별)
2. 시간대별 이용 시간
3. 앱 사용 순위 Top 1-30
4. 게임 카테고리 이용 특성
- 전체, 성별, 연령별, 요일별 사용 특성
5. 40대 사용자의 특성
[UBhind Analytics] 2015 6월 1,2주 주요지표 리포트Sung-Kwan Kim
UBhind Analytics 6월 첫번째 주요 지표 리포트 입니다.
분석기간 : 2015년 6월 1일 ~ 15일
1. 하루평균 스마트폰 사용시간(전체, 성별, 연령별)
2. 시간대별 이용 시간
3. 앱 사용 순위 Top 1-30
4. 소셜 카테고리 이용 특성
5. 30대 사용자의 특성
[UBhind Analytics] 2015 5월 3,4주 주요지표 리포트Sung-Kwan Kim
UBhind Analytics 5월 두번째 주요 지표 리포트 입니다.
분석기간 : 2015년 5월 16일 ~ 31일
1. 하루평균 스마트폰 사용시간(전체, 성별, 연령별)
2. 시간대별 이용 시간
3. 앱 사용 순위 Top 1-30
4. 커뮤니케이션 카테고리 이용 특성
5. 20대 사용자 특성
2. ✓ Objective-C 언어는 runtime 시에 많은 결정을 함.
✓ 컴파일된 코드를 실행하기 위해서는 컴파일러 뿐만
아니라 Runtime System이 필요함.
✓ Runtime System은 일종의 OS와 같이 동작.
- Objective-C 프로그램이 어떻게 runtime system과 상호작용하는지.
- 런타임시에 새로은 클래스를 어떻게 동적으로 로딩하는지.
- 다른 객체에게 어떻게 메시지를 전달하는지.
- 프로그램이 실행중인 동안 어떻게 객체에 대한 정보를 찾는지.
13년 5월 21일 화
3. Interacting with the Runtime
Objective-C 프로그램은 3가지 레벨에서 런타임 시스템과 상호작용
1. Objective-C Source Code
2. NSObject Methods
3. Runtime Functions
13년 5월 21일 화
4. ClassC의 객체
obj isa
stack Heap
Code
ClassC
-methodC
super
ClassB
-methodB
ClassA
super
-methodA
NSObject
super
NSNumber
-methodX +alloc
NSNumber의 객체
num
isa
super
-init -init
+alloc
객체 생성 과정
13년 5월 21일 화
5. Interacting with the Runtime
1. Objective-C Source Code
✓ 런타임 시스템의 동작은 보이지 않는 곳에서 자동으로 동작
✓ Objective-C 소스코드를 작성하고 컴파일하게 되면 런타임 시스템을 간접적으로
사용
✓ 코드를 컴파일 하게 되면 data structure와 언어의 동적인 특성을 구현한 함수
호출을 만들어 냄
✓ Data Structure
- Class와 Category 정의, Protocol 선언 정보
- method selector, instance variable templates, 그리고 소스 코드에서 추출된
다른 정보 등
13년 5월 21일 화
6. Interacting with the Runtime
2. NSObject Methods
✓ Cocoa에서 대부분의 객체는 NSObject 클래스의 서브클래스
✓ 몇몇 메소드는 런타임 시스템에 간단한 질의 수행
- 객체가 자신의 내부 정보를 획득(introspection)
- class
- isKindOfClass: , isMemberOfClass
- respondsToSelectors:
- conformsToProtocol:
- methodForSelectors:
13년 5월 21일 화
7. Interacting with the Runtime
3. Runtime Functions
✓ /usr/include/objc 에 있는 헤더 파일내의 데이터 구조나 함수의 조합
✓ 순수 C로 작성
✓ Objective-C 프로그래밍에는 필요하지 않음
✓ 런타임 시스템 인터페이스를 개발할 때 사용
13년 5월 21일 화
8. Messaging
Objective-C에서 메시지는 런타임까지 구현부에 바인딩 되지 않는다.
[receiver message] objc_msgSend(receiver, selector)
objc_msgSend(receiver, selector, arg1, arg2, ...)
✓ objc_msgSend(messaging function) 함수가 동적 바인딩에 필요한
모든 것을 수행.
- selector가 참조하는 procedure(method implementation)를 찾는다.
- 같은 함수가 다른 클래스에서 다르게 구현되어 있을 수 있기 때문에 정확한
procedure를 찾는 것은 receiver의 클래스에 달려있다.
- receiving object에 데이터 포인터 전달, procedure 호출.
- 처리 값 반환
✓ objc_msgSend 함수를 코드에서 직접 호출하면 안 됨!
13년 5월 21일 화
9. Messaging
‣ 모든 클래스 객체는 다음 두 가지 항목을 포함하고 있다.
✓ superclass에 대한 포인터
✓ class dispatch table
- selector와 함수 구현부의 주소를 연결
‣ 새로운 객체가 생성될 때 할당된 메모리와 인스턴스 변수들 초기화
‣ 객체의 변수들 중 첫번째는 클래스 구조에 대한 포인터
- isa 라고 부르를 포인터
- 클래스 자체와 클래스가 상속받은 모든 클래스에 대한 접근이 가능
- isa 포인터는 언어의 일부분이 아니지만, 런타임 시스템에서 동작하기 위해 필요
13년 5월 21일 화
10. Messaging
함수가 동적으로 메소드에 바인딩
되는 과정
메시지가 객체에 전달
isa 포인터를 참조
dispatch table 검색
superclass 포인터를 참조
dispatch table 검색
cache 검색(MRU)
13년 5월 21일 화
11. Using Hidden Arguments
✓ objc_msgSend가 procedure를 찾으면 호출하고, 메시지 내의 모든 인자를 전달
✓ 두개의 숨은 인자
- receiver
- selector
✓ 메소드를 정의한 코드에 선언되어 있지 않기 때문에 “hidden argument”
✓ 코드가 컴파일 될 때 삽입
✓ 메소드는 수신 객체를 self로, 자신에 대한 selector를 _cmd로 참조
13년 5월 21일 화
13. Getting a Method Address
✓ 동적 바인딩을 회피하는 유일한 방법은 메소드의 주소를 얻어서 마치 함수인 것
처럼 직업 호출하는 방법
- 특정 메소드가 많은 횟수 반복적으로 사용될 때 매번 메시징 하는 오버헤드를 피하고 싶을 때
사용
✓ NSObject 클래스에 정의된 methodForSelector 사용
- procedure의 포인터 조회
- 포인터를 사용하여 procedure 호출
- 포인터는 알맞은 함수 타입으로 형변환 해야 함!
void (*setter)(id, SEL, BOOL);
int i;
setter = (void (*)(id, SEL, BOOL))[target methodForSelector:@selector(setFilled:)];
for ( i = 0; i < 1000; i++ )
setter(targetList[i], @selector(setFilled:), YES);
13년 5월 21일 화
14. Getting a Method Address
@interface MyClass : NSObject {
}
-(void)doSomething;
@end
@implementation MyClass
-(void) doSomething {
// Do many many work
}
@end
MyClass* myObject = [ [ MyClass alloc ] init ] ;
SEL method = @selector(doSomething) ;
IMP func = [ myObject methodForSelector:method ] ;
func( myObject, method );
13년 5월 21일 화
15. Dynamic Method Resolution
✓ 동적으로 메소드를 제공해야할 경우가 종종 있다.(?)
- @dynamic propertyName;
- resolveInstanceMethod:
- resolveClassMethod:
- 주어진 selector에 대한 구현을 동적으로 제공
✓ Objective-C 메소드는 최소한 두개의 인자(self, _cmd)를 갖는 C 함수
✓ class_addMethod 함수를 사용하여 클래스에 함수를 메소드로 추가할 수 있음.
✓ Forwarding 메소드 또는 dynamic method resolution 둘 중 한가지 방법으로
동적 메소드 호출
✓ Forwarding 메커니즘을 시작하기 전에 dynamic method resolution 을 수행
13년 5월 21일 화
16. Dynamic Method Resolution
void dynamicMethodMP(id self, SEL _cmd) {
// implementation …
}
@implementation MyClass
+ (BOOL)resolveInstanceMethod:(SEL)aSEL {
if (aSEL == @selector(resolveThisMethodDynamically)) {
class_addMethod([self class], aSEL, (IMP) dynamicMethodIMP,“v@:”);
returnYES;
}
return [super resolveInstanceMethod:aSEL];
}
@end
13년 5월 21일 화
18. Message Forwarding
✓ 메시지 처리가 정의되어 있지 않은 객체에 메시지를 보내면 에러 발생
✓ 에러가 발생하기 전에 런타임 시스템은 메시지를 이해하고 있는 곳으로 메시지를
전달
==> Message Forwarding
✓ NSInvocation 객체를 단일 인자로 하는 forwardInvocation 메시지 전달
-(void)forwardInvocation:(NSInvocation *) anInvocation
✓ 이 메소드는 NSObject에서 정의되어 있기 때문에 모든 객체에 사용할 수 있음.
✓ NSInvocation객체에는 target, selector, parameter 같이 메세지 송신에 필요한 모든
정보가 들어있음.
13년 5월 21일 화
19. Message Forwarding
- negotiate {
if ( [someOtherObject respondsTo:@selector(negotiate)] )
return [someOtherObject negotiate];
return self;
}
13년 5월 21일 화
20. Message Forwarding
- (void)forwardInvocation:(NSInvocation *)anInvocation {
if ([someOtherObject respondsToSelector: [anInvocation selector]])
[anInvocation invokeWithTarget:someOtherObject];
else
[super forwardInvocation:anInvocation];
}
- 동적인 방법으로 메시지 전달
- 메시지 내의 selector와 일치하는 메소드가 없을 때 호출
- 원래 인자들과 함께 전달할 곳으로 보내야 함
- 전달된 메시지의 리턴값은 원래 호출자에게 돌아감
- 알 수 없는 메시지들을 서로 다른 수신자에게 배분하는 역할
(또는 모든 메시지를 같은 목적지로 보내는 역할)
- 객체에 전달한 메시지가 존재할 경우 forwardInvocation은 호출되지 않음
13년 5월 21일 화
21. Forwarding and Multiple Inheritance
✓ 포워딩은 다중 상속의 효과를 주는데 사용할 수 있다.
(다중 상속에서 원하는 대부분의 기능을 제공)
✓ 메시지를 전달하는 객체는 receiver가 메시지를 처리하는 것 처럼 보이며,
값을 리턴 받는다.
13년 5월 21일 화
22. Surrogate Object
✓ 다른 객체를 대신하고 메시지를 전달해주는 역할
✓ 크고, 무거운 동작을 수행하는 객체의 앞단에서 동작하는 객체
(경량 객체)
✓ 데이터에 관한 질의와 같은 간단한 처리는 직접 수행하고, 무거운 처리가 필요할
경우 실제 처리 객체에게 메시지 전달
✓ 커다란 객체로 향하는 모든 메시지는 surrogate를 통하게 되고, 다른 객체들은 두
객체를 동일하게 보게 됨
13년 5월 21일 화
23. Forwarding and Inheritance
✓ 포워딩이 상속과 유사하게 보일지라도, respondsToSelector: , isKindOfClass: 같은
메소드는 forwarding chain을 고려하지 않는다.
✓ 만약 포워딩 객체가 실제 객체의 모든 행위를 상속 받은 것 처럼 사용하고 싶다면,
위 메소드를 오버라이딩 해야 한다.
(BOOL)respondsToSelector:(SEL)aSelector
{
if ( [super respondsToSelector:aSelector] ) returnYES;
else { /* 이 부분에 aSelector 메시지가 *
* 다른 객체로 전달될 수 있는지 그리고 *
* 해당 객체가 메시지에 응답할 수 있는지를 체크하고 *
* 그럴수 있다면YES를 되돌리는 코드를 넣는다. */
}
return NO;
}
13년 5월 21일 화
24. Forwarding and Inheritance
✓ instancesRespondToSelector: , conformsToProtocol: 메소드 등도 필요에 따라
반영해야 한다.
✓ 객체가 원격지에서 수신한 모든 메시지를 전달한다면,
methodSignatureForSelector: 메소드 구현해야 한다.
(NSMethodSignature*)methodSignatureForSelector:(SEL)selector
{
NSMethodSignature* signature = [super methodSignatureForSelector:selector];
if (!signature) {
signature = [surrogate methodSignatureForSelector:selector];
}
return signature;
}
13년 5월 21일 화