runtime 입문 부터 정통 까지(9)-만능 인터페이스 점프

7194 단어 iOS-OC
글 의 길이 때문에 필 자 는 한 편의 글 로 runtime 을 사용 하여 만능 컨트롤 러 의 도약 을 실현 하 는 것 을 소개 한다.완전한 runtime 이 실제 개발 에서 사용 하 는 클릭 링크 보기->runtime 입문 부터 정통(6)-runtime 이 실제 개발 에서 의 응용
당신 의 개발 과정 에서 다음 과 같은 요 구 를 만난 적 이 있 습 니까?
4.567917.tableView 유형의 전시 목록 에서 모든 cell 에서 인물 의 프로필 사진 을 클릭 하면 인물 의 상세 한 상황 으로 이동 할 수 있 습 니 다.웨 이 보 의 프로필 사진 을 참조 할 수 있 습 니 다.마찬가지 로 퍼 가기,댓 글 버튼,각종 링크 와 linkcard 를 포함 합 니 다
  • 임의의 페이지 로 이동(1)제품 요구,한 페이지 의 서로 다른 배 너 그림,클릭 하면 모든 페이지 로 이동 할 수 있 습 니 다.원생 페이지 A,페이지 B 또는 웹 페이지 C 일 수 있 습 니 다.(2)웹 페이지 에서 모든 원생 페이지 로 이동 할 수 있 습 니 다.(3)원 격 푸 시 에서 임의로 지정 한 페이지 로 이동 합 니 다

  • 상기 두 가지 수 요 는 대부분 개발 자 들 이 만 났 고 이런 기능 을 실현 할 수 있다 고 생각 합 니 다.어쨌든 이것 은 비교적 기초적인 기능 이다.하지만 코드 가 그렇게 우아 한 것 은 아니다.
    일반 처리 방법
    1:일반 초보 자 들 은 target 이나 block 등 방법 으로 table View 의 대리 방법 으로 사건 을 받 고 실행 할 점프 를 contrller 에 기록 합 니 다.기능 은 실현 할 수 있 지만 문 제 는 이러한 cell 과 비슷 한 cell(구조 가 약간 변화 하거나 몇 개의 컨트롤 이 적 음)이 보통 여러 페이지 에 나타난다 는 것 이다.이렇게 되면 같은 코드 가 여러 곳 에 나타 날 것 이다.점프 방법 을 카 테 고리 로 뽑 아 써 도 target 이나 block 은 항상 곳곳에 써 야 합 니 다.
    2:초급 방법 은 모든 곳 에 판단 과 점프 를 쓰 는 것 이 고 고급 은 추출 하여 기본 클래스 나 category 에 쓰 는 것 입 니 다.
    우아 한 해결책(runtime 이용)
    runtime 동적 생 성 대상,속성,방법 이라는 특성 을 이용 하여 우 리 는 먼저 서버 와 상의 하여 점프 규칙 을 정의 할 수 있 습 니 다.예 를 들 어 A 컨트롤 러 로 이동 하려 면 속성 id,type 을 전달 해 야 합 니 다.그러면 서버 에서 사전 을 되 돌려 주 고 그 안에 컨트롤 러 이름,두 속성 이름과 속성 값 이 있 습 니 다.클 라 이언 트 는 컨트롤 러 이름 에 따라 대상 을 생 성 한 다음 에 kvc 로 대상 에 게 값 을 부여 할 수 있 습 니 다.이 정도 면 됐어.
    예 를 들 어 푸 시 규칙 에 따라 대응 하 는 인터페이스 HSFeedsView Controller
    HSFeedsViewController.h:
    이 인터페이스 에 들 어가 면 전송 해 야 할 속성
    @interface HSFeedsViewController : UIViewController
    //  :         ,                 
    /**   ID */
    @property (nonatomic, copy) NSString *ID;
    /**   type */
    @property (nonatomic, copy) NSString *type;
    @end

    AppDelegate.m 에 다음 코드 세 션 을 추가 합 니 다.
    보 내 온 메시지 규칙
    //                ,              
    NSDictionary *userInfo = @{
                               @"class": @"HSFeedsViewController",
                               @"property": @{
                                            @"ID": @"123",
                                            @"type": @"12"
                                       }
                               };

    푸 시 메 시 지 를 받다.
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
    {
        [self push:userInfo];
    }

    점프 인터페이스:
    - (void)push:(NSDictionary *)params
    {
        //   
        NSString *class =[NSString stringWithFormat:@"%@", params[@"class"]];
        const char *className = [class cStringUsingEncoding:NSASCIIStringEncoding];
        //           
        Class newClass = objc_getClass(className);
        if (!newClass)
        {
            //      
            Class superClass = [UIViewController class];
            newClass = objc_allocateClassPair(superClass, className, 0);
            //          
            objc_registerClassPair(newClass);
        }
        //     
        id instance = [[newClass alloc] init];
        //         
        NSDictionary * propertys = params[@"property"];
        [propertys enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
            //              
            if ([self checkIsExistPropertyWithInstance:instance verifyPropertyName:key]) {
                //   kvc  
                [instance setValue:obj forKey:key];
            }
        }];
        //        
        UITabBarController *tabVC = (UITabBarController *)self.window.rootViewController;
        UINavigationController *pushClassStance = (UINavigationController *)tabVC.viewControllers[tabVC.selectedIndex];
        //          
        [pushClassStance pushViewController:instance animated:YES];
    }

    검사 대상 에 이 속성 이 존재 하 는 지 여부:
    - (BOOL)checkIsExistPropertyWithInstance:(id)instance verifyPropertyName:(NSString *)verifyPropertyName
    {
        unsigned int outCount, i;
        //           
        objc_property_t * properties = class_copyPropertyList([instance
                                                               class], &outCount);
        for (i = 0; i < outCount; i++) {
            objc_property_t property =properties[i];
            //          
            NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
            //          
            if ([propertyName isEqualToString:verifyPropertyName]) {
                free(properties);
                return YES;
            }
        }
        free(properties);
        return NO;
    }

    구체 적 인 사용 과 코드:https://github.com/HHuiHao/Universal-Jump-ViewController

    좋은 웹페이지 즐겨찾기