runtime 기초 편 (2)

표 형의 블 로 그 를 옮 겨 실 었 는데, 정말 상세 하 게 썼 다.
방법 유형
Method 유형 은 하나의 objc_method 구조 체 지침 이 고 구조 체 objc_method 는 세 명의 구성원 이 있다.
/// An opaque type that represents a method in a class definition.
typedef struct objc_method *Method;

struct objc_method {
    SEL method_name;        //     
    char *method_typesE;    //             
    IMP method_imp;         //            
} 

방법 모든 방법
//     ,              
method_invoke
//     ,             
method_invoke_stret
//      
method_getName
//       IMP
method_getImplementation
//     type encoding
method_getTypeEncoding
//        
method_copyReturnType
//       
method_copyArgumentType
//        
method_getReturnType
//       
method_getNumberOfArguments
//         
method_getArgumentType
//       
method_getDescription
//       IMP
method_setImplementation
//        IMP
method_exchangeImplementations

함수 목록 가 져 오기
- (int)testInstanceMethod:(NSString *)name andValue:(NSNumber *)value {
  NSLog(@"%@", name);

  return value.intValue;
}

- (NSArray *)arrayWithNames:(NSArray *)names {
  NSLog(@"%@", names);
  return names;
}

- (void)getMethods {
  unsigned int outCount = 0;
  Method *methodList = class_copyMethodList(self.class, &outCount);

  for (unsigned int i = 0; i < outCount; ++i) {
    Method method = methodList[i];

    SEL methodName = method_getName(method);
    NSLog(@"   :%@", NSStringFromSelector(methodName));

    //          
    unsigned int argumentsCount = method_getNumberOfArguments(method);
    char argName[512] = {};
    for (unsigned int j = 0; j < argumentsCount; ++j) {
      method_getArgumentType(method, j, argName, 512);

      NSLog(@" %u      :%s", j, argName);
      memset(argName, '\0', strlen(argName));
    }

    char returnType[512] = {};
    method_getReturnType(method, returnType, 512);
    NSLog(@"     :%s", returnType);

    // type encoding
    NSLog(@"TypeEncoding: %s", method_getTypeEncoding(method));
  }

  free(methodList);
}

우 리 는 테스트 방법 을 써 서 호출 합 시다.
+ (void)test {
  HYBMethodLearn *m = [[HYBMethodLearn alloc] init];
  [m getMethods];

  //               
  int returnValue = ((int (*)(id, SEL, NSString *, NSNumber *))objc_msgSend)((id)m, @selector(testInstanceMethod:andValue:), @"       ", @100);
  NSLog(@"return value is %d", returnValue);
}

그 인쇄 결 과 는 다음 과 같다.
   :getMethods
 0      :@
 1      ::
     :v
TypeEncoding: v16@0:8
   :testInstanceMethod:andValue:
 0      :@
 1      ::
 2      :@
 3      :@
     :i
TypeEncoding: i32@0:8@16@24
   :arrayWithNames:
 0      :@
 1      ::
 2      :@
     :@
TypeEncoding: @24@0:8@16
       
return value is 100

왜 두 개의 인자 가 더 생 겼 습 니까?
methodgetNumberOfArguments 는 함수 의 모든 매개 변수 유형 을 가 져 옵 니 다. 위 에서 우리 가 정의 한 함수 에서 예 를 들 어 getMethods 는 매개 변수 가 없 는데 왜 두 개의 매개 변 수 를 인쇄 합 니까?그리고 - (int) test InstanceMethod: (NSString *) name and Value: (NSNumber *) value 는 두 개의 인자 밖 에 없 는데 왜 네 개의 인자 가 있 습 니까?다음은 우리 가 자세하게 말 하 겠 다.
  • 우선, 첫 번 째 방법 에 대해 컴 파일 할 때 이와 유사 하 게 변 환 됩 니 다.
  • ((void (*)(id, SEL))objc_msgSend)((id)m, @selector(getMethods));
    
  • 똑 같은 이치 로 두 번 째 방법 에 대해 컴 파일 할 때 컴 파일 러 는 이 를 이와 유사 하 게 변환 한다.
  • //               
    int returnValue = ((int (*)(id, SEL, NSString *, NSNumber *))
                     objc_msgSend)((id)m,
                                   @selector(testInstanceMethod:andValue:),
                                   @"       ",
                                   @100);
    

    함수 인 코딩
    methodgetTypeEncoding 은 함수 의 인 코딩 을 가 져 옵 니 다. 그 결 과 는 일련의 값 입 니 다.
  • 첫 번 째 방법의 인 코딩 은:v16@0:8
  • 두 번 째 방법의 인 코딩 은:i32@0:8@16@24
  • 세 번 째 방법의 인 코딩 은: @24@0:8@16

  • 그 러 고 보 니 뭘 알 수 있 을까요?이 몇 가지 값 을 보면 알 수 있다.
  • 첫 번 째 위 치 는 반환 값 유형 이다. 예 를 들 어 첫 번 째 방법 은 반환 값 이 V 이 고 두 번 째 는 i 이 며 세 번 째 는 @
  • 이다.
  • 두 번 째 / 세 번 째 위 치 는 첫 번 째 / 두 번 째 매개 변수 이 고 매개 변수 목록 은 왼쪽 에서 오른쪽으로 계산 합 니 다.각각 @:, @:, @:, 모두 대상 입 니 다. 사실 첫 번 째 와 두 번 째 인 자 는 고정 되 어 있 습 니 다. 첫 번 째 는 메 시 지 를 받 는 대상 이 고 두 번 째 는 방법 선택 기 SEL 입 니 다.
  • 다른 인자 가 있 으 면 순서대로...
  • 근 데 장르 뒤에 따 르 는 숫자 가 뭐 죠?사실 필자 도 잘 모 르 겠 지만 문 서 는 명확 하 게 설명 하지 않 았 지만 인쇄 결과 에서 그 규칙 을 알 수 있다.예 를 들 어 첫 번 째 방법: @ 의 오프셋 은 0,: 의 오프셋 은 8, v 의 오프셋 은 16 이 고 다른 방법 도 비슷 하 다.
    method_invoke objc_msgSend 함 수 를 사용 하 는 것 외 에 method_invoke 도 사용 할 수 있 습 니 다. 예 를 들 어:
    //     
    Method method = class_getInstanceMethod([self class], @selector(testInstanceMethod:andValue:));
    
    //     
    returnValue = ((int (*)(id, Method, NSString *, NSNumber *))method_invoke)((id)m, method, @"    method_invoke", @11);
    NSLog(@"call return vlaue is %d", returnValue);
    
    //                
    int returnValue = ((int (*)(id, SEL, NSString *, NSNumber *))
                     objc_msgSend)((id)m,
                                   @selector(testInstanceMethod:andValue:),
                                   @"       ",
                                   @100);
    NSLog(@"return value is %d", returnValue);
    

    Type Encoding
    부호화 값
    속뜻
    c
    대표 char 형식
    i
    대표 int 형식
    s
    대표 short 형식
    l (소문 자 L)
    log 형식 을 대표 하 며 64 비트 프로세서 에서 도 32 비트 로 처리 합 니 다.
    q
    대표 long long 유형
    C
    서명 되 지 않 은 char 형식 을 대표 합 니 다.
    I (대문자 i)
    서명 되 지 않 은 int 형식 을 대표 합 니 다.
    S
    서명 되 지 않 은 짧 은 형식 을 대표 합 니 다.
    L
    서명 되 지 않 은 long 형식 을 대표 합 니 다.
    Q
    서명 되 지 않 은 long 형식 을 대표 합 니 다.
    f
    대표 float 유형
    d
    대표 double 형식
    B
    C + + 의 bool 또는 C99 를 대표 하 는Bool
    v
    void 형식
    *
    대표 char * 형식
    @
    대표 대상 유형
    #
    대표 클래스 대상 (Class)
    :
    대표 방법 selector (SEL)
    [array type]
    대표 array
    {name=type…}
    대표 구조 체
    (name=type…)
    대표 조합
    bnum
    A bit field of num bits
    ^type
    A pointer to type
    ?
    An unknown type (among other things, this code is used for function pointers)

    좋은 웹페이지 즐겨찾기