FrameWork Learning - Mantle

19087 단어 iosmantle
Mantle 은 Cocoa 나 Cocoa Touch 프로그램 에서 model 층 을 간소화 하 는 제3자 라 이브 러 리 입 니 다.일반적으로 우 리 는 대량의 model 을 정의 하여 각종 데이터 구 조 를 나타 내 는데, 이러한 model 의 초기 화 와 인 코딩 디 코딩 은 대량의 코드 를 써 야 한다.맨틀 의 장점 은 이 코드 들 을 크게 간소화 할 수 있다 는 점 이다.
Mantle 소스 코드 의 가장 주요 한 내용 은:
  • MTLModel 류: 보통 우리 모델 의 기본 클래스 로 서 이 종 류 는 대상 의 초기 화 와 압축 파일 작업 을 처리 하 는 기본 적 인 행 위 를 제공 하 는 동시에 대상 의 모든 속성의 키 집합 을 얻 을 수 있 습 니 다.
  • MTLJSONadapter 류: MTLModel 대상 과 JSON 사전 간 의 상호 전환 에 사용 되 며 어댑터 에 해당 합 니 다.
  • MTLJSONserializing 협의: JSON 사전 과 상호 전환 이 필요 한 MTLModel 의 하위 클래스 는 모두 이 협 의 를 실현 하여 MTLJSONapadter 대상 의 전환 을 편리 하 게 해 야 한다.

  • 여기 서 이 세 가 지 를 우리 의 분석 점 으로 삼 는 다.
    기본 MTLModel
    MTLModel 은 추상 적 인 유형 으로 대상 의 초기 화 와 압축 파일 작업 을 처리 하 는 기본 적 인 행 위 를 제공 합 니 다.
    초기 화
    MTLModel 의 기본 초기 화 방법 - init 는 아무 일 도 하지 않 고 [슈퍼 init] 만 호출 했 습 니 다.동시에 다른 초기 화 방법 을 제공 합 니 다.
    - (instancetype)initWithDictionary:(NSDictionary *)dictionaryValue error:(NSError **)error;

    그 중에서 매개 변수 dictionary Value 는 사전 으로 대상 을 초기 화 하 는 key - value 쌍 을 포함 합 니 다.우 리 는 그것 의 구체 적 인 실현 을 살 펴 보 자.
    - (instancetype)initWithDictionary:(NSDictionary *)dictionary error:(NSError **)error {
        ...
        for (NSString *key in dictionary) {
            // 1.  value   __autoreleasing,     MTLValidateAndSetValue   ,
            //                      
            __autoreleasing id value = [dictionary objectForKey:key];
            // 2. value   NSNull.null,          nil
            if ([value isEqual:NSNull.null]) value = nil;
            // 3. MTLValidateAndSetValue    KVC     value    key    ,
            //        ,           key  。
            //              KVC    value    model   key   。
            //      MTLValidateAndSetValue        ,        。
            BOOL success = MTLValidateAndSetValue(self, key, value, YES, error);
            if (!success) return nil;
        }
        ...
    }

    하위 클래스 는 이 방법 을 다시 쓸 수 있 습 니 다. 대상 의 속성 을 설정 한 후에 진일보 한 처리 나 초기 화 작업 을 할 수 있 습 니 다. 그러나 기억 해 야 할 것 은 슈퍼 를 통 해 부모 클래스 의 실현 을 호출해 야 한 다 는 것 입 니 다.
    속성의 키 (key), 값 (value) 가 져 오기
    MTLModel 클래스 는 클래스 방법 + propertyKeys 를 제공 합 니 다. 이 방법 은 모든 @ property 성명 의 속성 에 대응 하 는 이름 문자열 의 집합 을 되 돌려 줍 니 다. 단, 속성 과 MTLModel 자체 의 속성 만 읽 는 것 은 포함 되 지 않 습 니 다.이 방법 은 model 의 모든 속성 을 옮 겨 다 닙 니 다. 속성 이 읽 기만 하고 ivar 값 이 NULL 이 아니라면 속성 명 을 나타 내 는 문자열 을 가 져 와 집합 에 넣 습 니 다. 이 는 다음 과 같 습 니 다.
    + (NSSet *)propertyKeys {
        // 1.                 ,       。             。
        NSSet *cachedKeys = objc_getAssociatedObject(self, MTLModelCachedPropertyKeysKey);
        if (cachedKeys != nil) return cachedKeys;
        NSMutableSet *keys = [NSMutableSet set];
        // 2.          
        //    enumeratePropertiesUsingBlock     superclass        MTLModel,
        //        model               (   MTLModel),       block    。
        //      enumeratePropertiesUsingBlock        ,        。
        [self enumeratePropertiesUsingBlock:^(objc_property_t property, BOOL *stop) {
            mtl_propertyAttributes *attributes = mtl_copyPropertyAttributes(property);
            @onExit {
                free(attributes);
            };
            // 3.        ivar NULL   
            if (attributes->readonly && attributes->ivar == NULL) return;
            // 4.         ,       
            NSString *key = @(property_getName(property));
            [keys addObject:key];
        }];
        // 5.            。
        objc_setAssociatedObject(self, MTLModelCachedPropertyKeysKey, keys, OBJC_ASSOCIATION_COPY);
        return keys;
    }

    위 와 같은 방법 이 있 습 니 다. 대상 의 모든 속성 과 해당 하 는 값 을 얻 으 려 면 방법 입 니 다.이 를 위해 MTLModel 은 현재 model 의 모든 속성 과 값 을 포함 하 는 사전 을 읽 기 전용 속성 dictionary Value 를 제공 합 니 다.속성 값 이 nil 이면 NSNull 로 대체 합 니 다.또한 이 속성 은 nil 이 아 닙 니 다.
    @property (nonatomic, copy, readonly) NSDictionary *dictionaryValue;
    //   
    - (NSDictionary *)dictionaryValue {
        return [self dictionaryWithValuesForKeys:self.class.propertyKeys.allObjects];
    }

    병합 대상
    합병 대상 은 두 MTLModel 대상 을 사용자 정의 방법 에 따라 대응 하 는 속성 값 을 합 치 는 것 을 말한다.이 를 위해 MTLModel 에서 다음 과 같은 방법 을 정의 했다.
    - (void)mergeValueForKey:(NSString *)key fromModel:(MTLModel *)model;

    이 방법 은 현재 대상 이 지정 한 key 속성의 값 과 model 매개 변수 에 대응 하 는 속성 값 을 지정 한 규칙 에 따라 통합 합 니 다. 이 규칙 은 우리 가 사용자 정의 - merge FromModel: 방법 으로 확정 합 니 다.만약 우리 의 하위 클래스 에서 - merge FromModel: 방법 을 실현 한다 면 그것 을 호출 할 것 입 니 다.찾 지 못 하고 model 이 nil 이 아니라면 model 의 속성 값 으로 현재 대상 의 속성 값 을 대체 합 니 다.구체 적 인 실현 은 다음 과 같다.
    - (void)mergeValueForKey:(NSString *)key fromModel:(MTLModel *)model {
        NSParameterAssert(key != nil);
        // 1.      key  "mergeFromModel:"   ,             selector
        //              -mergeFromModel:  , model  nil,  model    
        //              
        //
        //    MTLSelectorWithCapitalizedKeyPattern   C             ,     
        //        ,       
        SEL selector = MTLSelectorWithCapitalizedKeyPattern("merge", key, "FromModel:");
        if (![self respondsToSelector:selector]) {
            if (model != nil) {
                [self setValue:[model valueForKey:key] forKey:key];
            }
            return;
        }
        // 2.   NSInvocation        -mergeFromModel:  。
        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:selector]];
        invocation.target = self;
        invocation.selector = selector;
        [invocation setArgument:&model atIndex:2];
        [invocation invoke];
    }

    그 밖 에 MTLModel 은 두 대상 의 모든 속성 치 를 합병 하 는 또 다른 방법 을 제공 했다. 즉,:
    - (void)mergeValuesForKeysFromModel:(MTLModel *)model;

    주의해 야 할 것 은 model 은 현재 대상 이 속 한 클래스 나 하위 클래스 여야 합 니 다.
    압축 파일 대상 (아 카 이브)
    맨틀 은 MTLModel 에 대한 인 코딩 디 코딩 처 리 를 MTLModel 의 NSCoding 분류 에 넣 어 처 리 했 으 며, 이 분류 및 관련 정 의 는 MTLModel + NSCoding 파일 에 담 았 다.
    서로 다른 속성 에 대해 인 코딩 디 코딩 과정 에서 차별 화 될 수 있 습 니 다. 이 를 위해 Mentle 은 MTLModel Encoding Behavior 를 매 거 하여 MTLModel 속성 이 압축 파일 에 인 코딩 된 행 위 를 확인 합 니 다.그 정 의 는 다음 과 같다.
    typedef enum : NSUInteger {
        MTLModelEncodingBehaviorExcluded = 0,           //          
        MTLModelEncodingBehaviorUnconditional,          //          
        MTLModelEncodingBehaviorConditional,            //                       。         
    } MTLModelEncodingBehavior;

    모든 속성의 압축 파일 행 위 를 구체 적 으로 설정 할 수 있 습 니 다.MTLModel 류 는 우리 에 게 기본 적 인 실현 을 제공 합 니 다. 다음 과 같 습 니 다.
    + (NSDictionary *)encodingBehaviorsByPropertyKey {
        // 1.         
        NSSet *propertyKeys = self.propertyKeys;
        NSMutableDictionary *behaviors = [[NSMutableDictionary alloc] initWithCapacity:propertyKeys.count];
        // 2.           
        for (NSString *key in propertyKeys) {
            objc_property_t property = class_getProperty(self, key.UTF8String);
            NSAssert(property != NULL, @"Could not find property \"%@\" on %@", key, self);
            mtl_propertyAttributes *attributes = mtl_copyPropertyAttributes(property);
            @onExit {
                free(attributes);
            };
            // 3.     weak ,     MTLModelEncodingBehaviorConditional,     MTLModelEncodingBehaviorUnconditional,    ,     NSNumber       。
            MTLModelEncodingBehavior behavior = (attributes->weak ? MTLModelEncodingBehaviorConditional : MTLModelEncodingBehaviorUnconditional);
            behaviors[key] = @(behavior);
        }
        return behaviors;
    }

    이 되 돌아 오지 않 는 사전 의 속성 은 압축 되 지 않 습 니 다.하위 클래스 는 자신의 수요 에 따라 각 속성의 압축 파일 행 위 를 지정 할 수 있 습 니 다.그러나 실제 적 으로 슈퍼 를 통 해 부류 의 실현 을 호출해 야 한다.
    압축 파일 에서 지정 한 속성 을 디 코딩 하기 위해 Mantle 은 다음 과 같은 방법 을 제공 합 니 다.
    - (id)decodeValueForKey:(NSString *)key withCoder:(NSCoder *)coder modelVersion:(NSUInteger)modelVersion;

    기본적으로 이 방법 은 현재 대상 에서 - decodeWith Coder: model 버 전과 유사 한 방법 을 찾 습 니 다. 찾 으 면 해당 방법 을 호출 하고 사용자 정의 방식 으로 속성 디 코딩 을 처리 합 니 다.사용자 정의 방법 이나 coder 가 보안 인 코딩 이 필요 하지 않 으 면 지정 한 key 호출 - [NSCoder decodeObject ForKey:] 방법 을 사용 합 니 다.그 구체 적 인 실현 은 다음 과 같다.
    - (id)decodeValueForKey:(NSString *)key withCoder:(NSCoder *)coder modelVersion:(NSUInteger)modelVersion {
        ...
        SEL selector = MTLSelectorWithCapitalizedKeyPattern("decode", key, "WithCoder:modelVersion:");
        // 1.       -decodeWithCoder:modelVersion:  ,   NSInvocation     
        if ([self respondsToSelector:selector]) {
            NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:selector]];
            invocation.target = self;
            invocation.selector = selector;
            [invocation setArgument:&coder atIndex:2];
            [invocation setArgument:&modelVersion atIndex:3];
            [invocation invoke];
            __unsafe_unretained id result = nil;
            [invocation getReturnValue:&result];
            return result;
        }
        @try {
            // 2.           -decodeWithCoder:modelVersion:  ,
            //          。
            //
            // coderRequiresSecureCoding            
            if (coderRequiresSecureCoding(coder)) {
                // 3.   coder      ,                       ,      
                //                。
                //      ,MTLModel      allowedSecureCodingClassesByPropertyKey,   
                //                               。            
                //         ,             。               ,
                //             ,            ,          NSValue,
                //          ,            。
                //                  。
                NSArray *allowedClasses = self.class.allowedSecureCodingClassesByPropertyKey[key];
                NSAssert(allowedClasses != nil, @"No allowed classes specified for securely decoding key \"%@\" on %@", key, self.class);
                return [coder decodeObjectOfClasses:[NSSet setWithArray:allowedClasses] forKey:key];
            } else {
                // 4.        
                return [coder decodeObjectForKey:key];
            }
        } @catch (NSException *exception) {
            ...
        }
    }

    물론 모든 인 코딩 디 코딩 작업 은 - init With Coder: 와 - encodeWith Coder: 두 가지 방법 으로 이 루어 져 야 합 니 다.우 리 는 MTLModel 의 하위 클래스 를 정의 할 때 자신의 수요 에 따라 특정한 속성 을 처리 할 수 있 지만 슈퍼 의 실현 을 호출 하여 부모 클래스 의 작업 을 수행 하 는 것 이 좋 습 니 다.MTLModel 은 이 두 가지 방법의 실현 에 대해 소스 코드 를 참고 하 시기 바 랍 니 다. 여기 서 설명 을 많이 하지 않 습 니 다.
    어댑터 MTLJSONapadter
    MTLModel 대상 과 JSON 사전 간 의 상호 전환 을 편리 하 게 하기 위해 Mantle 은 이러한 MTLJSONapadter 를 제공 하여 이 두 가지 어댑터 로 한다.
    MTLJSONserializing 프로 토 콜
    Mantle 은 JSON 사전 과 상호 전환 이 필요 한 MTLModel 의 하위 클래스 가 MTLJSONserializing 을 실현 하여 MTLJSONapadter 대상 의 전환 을 편리 하 게 해 야 한다 고 정의 했다.이 협의 에서 세 가지 방법 을 정 의 했 는데 구체 적 으로 다음 과 같다.
    @protocol MTLJSONSerializing
    @required
    + (NSDictionary *)JSONKeyPathsByPropertyKey;
    @optional
    + (NSValueTransformer *)JSONTransformerForKey:(NSString *)key;
    + (Class)classForParsingJSONDictionary:(NSDictionary *)JSONDictionary;
    @end

    이 세 가지 방법 은 모두 같은 방법 이다.그 중에서 + JSONkey Pathsby Property Key 는 반드시 이 루어 져 야 합 니 다. 되 돌아 오 는 사전 은 대상 의 속성 을 JSON 의 서로 다른 key path (문자열 값 이나 NSNull) 에 어떻게 표시 하 는 지 지정 합 니 다.이 사전 에 없 는 속성 은 JSON 에서 사용 하 는 key 값 과 일치 하 는 것 으로 여 겨 집 니 다.NSNull 에 비 친 속성 은 JSON 서열 화 과정 에서 처리 되 지 않 습 니 다.
    + JSONtransformerForKey: 방법 은 JSON 값 을 지정 한 속성 값 으로 변환 하 는 방법 을 지정 합 니 다.반대로 변환기 도 속성 값 을 JSON 값 으로 변환 하 는 데 사용 된다.변환기 가 + JSONtransformer 방법 을 실현 하면 MTLJSONadapter 는 이 구체 적 인 방법 을 사용 하고 + JSONtransformerForKey: 방법 을 사용 하지 않 습 니 다.또한 사용자 정의 변환 이 필요 하지 않 으 면 nil 로 돌아 갑 니 다.
    재 작성 + classForParsingJSONdictionary: 방법 은 현재 모델 을 다른 클래스 의 대상 으로 해석 할 수 있 습 니 다.이 대상 클래스 는 매우 유용 합 니 다. 그 중에서 추상 적 인 기 류 는 - [MTLJSONadapter initWithJSONdictionary: model Class:] 방법 에 전달 되 고 실례 화 된 것 은 하위 클래스 입 니 다.
    만약 우리 가 MTLModel 의 하위 클래스 가 MTLJSONapadter 를 사용 하여 전환 할 수 있 기 를 원한 다 면 이 협 의 를 실현 하고 해당 하 는 방법 을 실현 해 야 한다.
    초기 화
    MTLJSONapadter 대상 은 읽 기 전용 속성 이 있 습 니 다. 이 속성 은 어댑터 가 처리 해 야 할 MTLModel 대상 입 니 다. 그 성명 은 다음 과 같 습 니 다.
    @property (nonatomic, strong, readonly) MTLModel
    *model;

    이 대상 은 MTLJSONserializing 합 의 를 실현 한 MTLModel 대상 이 어야 한 다 는 것 을 알 수 있다.이 속성 은 읽 기 전용 이기 때문에 초기 화 방법 으로 만 초기 화 할 수 있 습 니 다.
    MTLJSONapadter 대상 은 - init 를 통 해 초기 화 할 수 없 으 며 이 방법 은 직접적 으로 단언 합 니 다.클래스 가 제공 하 는 두 가지 초기 화 방법 을 통 해 초기 화 해 야 합 니 다. 다음 과 같 습 니 다.
    - (id)initWithJSONDictionary:(NSDictionary *)JSONDictionary modelClass:(Class)modelClass error:(NSError **)error;
    - (id)initWithModel:(MTLModel*)model;

    그 중에서 - (id) initWithJSONdictionary: modelclass: error: 사전 과 변환 할 클래스 를 사용 하여 초기 화 합 니 다.사전 JSONdictionary 는 JSON 데 이 터 를 표시 합 니 다. 이 사전 은 NSJSONserialization 이 되 돌아 오 는 형식 에 부합 해 야 합 니 다.이 인자 가 비어 있 으 면 nil 을 되 돌려 주 고 MTLJSONadapter Error InvalidJSONdictionary 코드 가 있 는 error 대상 을 되 돌려 줍 니 다.이 방법의 구체 적 인 실현 은 다음 과 같다.
    - (id)initWithJSONDictionary:(NSDictionary *)JSONDictionary modelClass:(Class)modelClass error:(NSError **)error {
        ...
        if (JSONDictionary == nil || ![JSONDictionary isKindOfClass:NSDictionary.class]) {
            ...
            return nil;
        }
        if ([modelClass respondsToSelector:@selector(classForParsingJSONDictionary:)]) {
            modelClass = [modelClass classForParsingJSONDictionary:JSONDictionary];
            if (modelClass == nil) {
                ...
                return nil;
            }
            ...
        }
        ...
        _modelClass = modelClass;
        _JSONKeyPathsByPropertyKey = [[modelClass JSONKeyPathsByPropertyKey] copy];
        NSMutableDictionary *dictionaryValue = [[NSMutableDictionary alloc] initWithCapacity:JSONDictionary.count];
        NSSet *propertyKeys = [self.modelClass propertyKeys];
        // 1.   model +JSONKeyPathsByPropertyKey   key-value     
        for (NSString *mappedPropertyKey in self.JSONKeyPathsByPropertyKey) {
            // 2.   model        +JSONKeyPathsByPropertyKey             
            //       nil。 +JSONKeyPathsByPropertyKey           model     
            //       。
            if (![propertyKeys containsObject:mappedPropertyKey]) {
                ...
                return nil;
            }
            id value = self.JSONKeyPathsByPropertyKey[mappedPropertyKey];
            // 3.            JSON       NSNull,   nil。
            if (![value isKindOfClass:NSString.class] && value != NSNull.null) {
                ...
                return nil;
            }
        }
        for (NSString *propertyKey in propertyKeys) {
            NSString *JSONKeyPath = [self JSONKeyPathForPropertyKey:propertyKey];
            if (JSONKeyPath == nil) continue;
            id value;
            @try {
                value = [JSONDictionary valueForKeyPath:JSONKeyPath];
            } @catch (NSException *ex) {
                ...
                return nil;
            }
            if (value == nil) continue;
            @try {
                // 4.        ,
                //        ,+JSONTransformerForKey:        +JSONTransformer  ,
                //                  ,    ,      +JSONTransformerForKey:  
                //                
                NSValueTransformer *transformer = [self JSONTransformerForKey:propertyKey];
                if (transformer != nil) {
                    // 5.           
                    if ([value isEqual:NSNull.null]) value = nil;
                    value = [transformer transformedValue:value] ?: NSNull.null;
                }
                dictionaryValue[propertyKey] = value;
            } @catch (NSException *ex) {
                ...
                return nil;
            }
        }
        // 6.    _model
        _model = [self.modelClass modelWithDictionary:dictionaryValue error:error];
        if (_model == nil) return nil;
        return self;
    }

    또한 MTLJSONapadter 는 MTLJSONapadter 대상 을 만 드 는 몇 가지 방법 을 제공 했다. 다음 과 같다.
    + (id)modelOfClass:(Class)modelClass fromJSONDictionary:(NSDictionary *)JSONDictionary error:(NSError **)error;
    + (NSArray *)modelsOfClass:(Class)modelClass fromJSONArray:(NSArray *)JSONArray error:(NSError **)error;
    + (NSDictionary *)JSONDictionaryFromModel:(MTLModel*)model;

    구체 적 으로 실현 하면 소스 코드 를 참고 할 수 있다.
    대상 에서 JSON 데이터 가 져 오기
    MTLModel 대상 에서 JSON 데 이 터 를 얻 는 것 은 상기 초기 화 과정 중의 역 과정 이다.이 과정 은 - JSONdictionary 방법 으로 이 루어 집 니 다. 구체 적 으로 다음 과 같 습 니 다.
    - (NSDictionary *)JSONDictionary {
        NSDictionary *dictionaryValue = self.model.dictionaryValue;
        NSMutableDictionary *JSONDictionary = [[NSMutableDictionary alloc] initWithCapacity:dictionaryValue.count];
        [dictionaryValue enumerateKeysAndObjectsUsingBlock:^(NSString *propertyKey, id value, BOOL *stop) {
            NSString *JSONKeyPath = [self JSONKeyPathForPropertyKey:propertyKey];
            if (JSONKeyPath == nil) return;
            // 1.       
            NSValueTransformer *transformer = [self JSONTransformerForKey:propertyKey];
            if ([transformer.class allowsReverseTransformation]) {
                if ([value isEqual:NSNull.null]) value = nil;
                value = [transformer reverseTransformedValue:value] ?: NSNull.null;
            }
            NSArray *keyPathComponents = [JSONKeyPath componentsSeparatedByString:@"."];
            // 2.           ,   keypath        ,
            //           obj      ,          ;         ,    
            //               : @{@"nested": @{@"name": @"foo"}}
            id obj = JSONDictionary;
            for (NSString *component in keyPathComponents) {
                if ([obj valueForKey:component] == nil) {
                    [obj setValue:[NSMutableDictionary dictionary] forKey:component];
                }
                obj = [obj valueForKey:component];
            }
            [JSONDictionary setValue:value forKeyPath:JSONKeyPath];
        }];
        return JSONDictionary;
    }

    위 에서 알 수 있 듯 이 이 방법 은 실제로 하나의 사전 을 얻 었 다.사전 을 얻 은 뒤 JSON 꼬치 로 서열 화하 기 가 쉽다.
    MTLJSONapadter 도 하나의 model 에서 JSON 사전 을 얻 을 수 있 는 간단 한 방법 을 제공 합 니 다. 그 정 의 는 다음 과 같 습 니 다.
    + (NSDictionary *)JSONDictionaryFromModel:(MTLModel
    *)model;

    MTLManagedObjectAdapter
    코어 데이터 에 적응 하기 위해 맨틀 은 MTLManaged ObjectAdapter 류 를 전문 적 으로 정의 했다.이 종 류 는 MTLModel 대상 과 NSManaged Object 대상 이전의 전환 에 사용 된다.구체 적 인 것 은 여기 서 상세 하 게 설명 하지 않 겠 습 니 다.
    기술 점 총화
    Mantle 의 기능 은 주로 대상 간 의 데 이 터 를 전환 하 는 것 이다. 즉, MTLModel 과 JSON 사전 에서 데 이 터 를 어떻게 전환 하 는 지 하 는 것 이다.따라서 사용 하 는 기술 은 대부분 코코아 파운데이션 이 제공 하 는 기능 이다.Core Data 에 대한 처 리 를 제외 하고 주로 사용 하 는 기술 은 다음 과 같은 몇 가지 가 있 습 니 다.
    KVC 의 응용: 이것 은 주로 MTLModel 하위 클래스 의 속성 할당 에 나타 나 고 KVC 체 제 를 통 해 값 의 유효성 을 검증 하고 속성 할당 에 나타난다.
    NSValueTransform: 이것 은 주로 JSON 값 을 속성 값 으로 변환 하 는 데 사 용 됩 니 다. 우 리 는 변환 기 를 사용자 정의 하여 우리 자신의 변환 수 요 를 만족 시 킬 수 있 습 니 다.
    NSInvocation: 이것 은 주로 특정한 key 값 에 대한 호출 을 통일 적 으로 처리 하 는 데 사 용 됩 니 다.예 를 들 어 - merge FromModel: 이런 방법.
    Run time 함수 사용: 문자열 에서 방법 에 대응 하 는 문자열 을 가 져 온 다음 selregisterName 함수 로 selector 를 등록 합 니 다.
    물론 Mantle 에 서 는 다른 기술 점 도 언급 되 어 서술 을 많이 하지 않 는 다.

    좋은 웹페이지 즐겨찾기