MJExtension 일반적인 방법

A, MJExtension 타사 프레임 워크

우리는 아이폰 OS 개발 과정, 우리는 종종 데이터가 반환 마이크로 블로그 네트워크 요청으로 사전 데이터 (즉, JSON 데이터) 및 모델 모델 사이의 변환해야하고, 우리는 모든 수동 모델을 소유하고있는 경우 등, 생성 및 할당 일부는 기술적 인 내용 코드 없으며, 많은 시간이 소요, 또한 잘못 지정 우리에게 두통을 할 수 있습니다.

MJExtension 프레임 워크는이 문제가 타사 오픈 소스 라이브러리를 해결하기 위해 설계되었습니다. 도서관은 교사에 의해 작성 치 사천 강사 리튬 Mingjie 블로그 전에 열려, 지금 그 자신 아웃 할, 나는 리 Mingjie 아이폰 OS는 항목이 교사 교육 비디오를 배우는 참조, 그는 아주 잘 말하고, 내가 그를 좋아, 그는 고려 될 수있다 선생님은, 그의 작품은 아직도에서 배울 수있다.

그것은 다음과 같은 몇 가지 방법을 제공합니다 :

  1. 간단한 사전 -> 모델
  2. JSON 문자열 -> 모델
  3. 복잡한 사전 -> 모델 (모델을 포함 모델)
  4. 복잡한 사전 -> 모델 (모델 배열 속성 내부 모델 가득)
  5. 복잡한 사전 -> 모델 (키 속성 이름과 모델 사전은 동일하지 않습니다)
  6. 사전 배열 -> 배열 모델
  7. 모델 -> 사전
  8. 모델 배열 -> 배열 사전
  9. 사전 -> CoreData 모델
  10. 아카이브 및 아카이브되지 NSCoding
  11. 값 필터 사전

오히려하지 스위프트 언어는이 특성을 가지고 있는지를 Obj-C 실행할 때 MJExtension 프레임 워크는 메커니즘을 사용하여 작성, 지금은 언어 발달에 아이폰 OS 스위프트 개발 언어, 나도 몰라, 프레임 워크의 미래는 스위프트 언어로 개발한다 알고 있지만, 주니어 개발자가 소스 코드를 볼 수 있도록이 프레임 워크는 매우 적합한, 매우 가볍고,의 Obj-C 메커니즘의 작동을 이해하는 데 매우 큰 도움이있다.

두 런타임 런타임 메커니즘을 이해하는 것이 간단합니다

런타임 짧은 실행되고, 시스템이 실행되는 몇 가지 메커니즘이 가장 중요한 메시지 메커니즘이다.

OC 유사한 함수 호출 메시지는 동적 호출 절차이다. 컴파일시에 당신은 정말 전화 기능을 결정할 수 없습니다. 이 컴파일 단계는, OC만큼 오류가 언급 오버하지 않으므로, 함수가 달성되지 않은 경우에도, 어떤 함수를 호출 할 수 있습니다 것으로 나타났다. C 언어 컴파일 타임에 오류를 줄 것이다. 당신은 당신이 실제로 함수의 이름에 따라 실행할 때 호출 할 해당 기능을 찾을 수 있습니다.

예를 들어, 다음 코드는 컴파일시에 변환됩니다 :

/* OC方法调用 */
[obj makeTest];
/* 编译时Runtime会将上面的代码转为下面的消息发送 */
objc_msgSend(obj, @selector(makeText)); 

아이폰 OS 위에 NSObject의 기본 클래스 포인터는 ISA objc_class 구조에 대한 포인터를 포함합니다 :

@interface NSObject{
Class isa;
};
typedef struct objc_class *Class; struct objc_class { Class isa; // 指向metaclass,也就是静态的Class Class super_class ; // 指向其父类 const char *name ; // 类名 long version ; // 类的版本信息,初始化默认为0 /* 一些标识信息,如CLS_CLASS(0x1L)表示该类为普通class; CLS_META(0x2L)表示该类为metaclass */ long info; long instance_size ; // 该类的实例变量大小(包括从父类继承下来的实例变量 struct objc_ivar_list *ivars; // 用于存储每个成员变量的地址 /* 与info的一些标志位有关,如是普通class则存储对象方法,如是metaclass则存储类方法 */ struct objc_method_list **methodLists ; struct objc_cache *cache; // 指向最近使用的方法的指 针,用于提升效率; struct objc_protocol_list *protocols; // 存储该类 遵守的协议 }; 
 
1795722-93c68c68674d07ee.jpg

objc_msgSend 기능에서 프로 시저를 호출 :

  1. 첫째, OBJ의 클래스에 의해 해당 OBJ의 ISA 포인터를 찾을 수 있습니다.
  2. 클래스에서 SEL에 의해 대응 방법을 찾기 위해 캐시 기능으로 이동
  3. 캐시가 발견되지 않는 경우, methodLists 보면 이동
  4. methodLists를 찾을 수 없습니다 경우, 슈퍼 클래스 이전 단계를 입력하여 재귀 조회
  5. 상기 방법이 발견되면, 본 방법은 다음의 검색을 용이하게하고 실행하는 함수 포인터 방법을 통해 해당 기능으로 점프하기 위해 캐시에 추가된다.
  6. 당신은 NSObject를 찾을 수 없습니다 발견 된 경우, 메시지를 동적 프로세스를 입력합니다.

동적 메시지 처리 흐름 :

/* 1\. 时机处理之一,在这个方法中我们可以利用runtime的特性动态添加方法来处理 */
+ (BOOL)resolveInstanceMethod:(SEL)sel;
/* 2\. 时机处理之二,在这个方法中看代理能不能处理,如果代理对象能处理,则转接给代理对象 */
- (id)forwardingTargetForSelector:(SEL)aSelector;
/* 3\. 消息转发之一,该方法返回方法签名,如果返回nil,则转发流程终止,抛出异常 */ - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector; /* 4\. 消息转发之二,在该方法中我们可以对调用方法进行重定向 */ - (void)forwardInvocation:(NSInvocation *)anInvocation; 
 
1795722-008e4e09b0e93dd7.jpg

그래서 우리는 동적으로 메소드 나 클래스 속성을 추가하는 런타임 메커니즘을 사용할 수 있습니다 :

/* 动态向一个类添加属性 */
class_addIvar(kclass, "expression", size, alignment, "*");
/* 动态向一个类添加方法 */
class_addMethod(kclass, @selector(setExpressionFormula:), (IMP)setExpressionFormula, "v@:@"); class_addMethod(kclass, @selector(getExpressionFormula), (IMP)getExpressionFormula, "@@:"); static void setExpressionFormula(id self, SEL cmd, id value){ NSLog(@"call setExpressionFormula"); } static id getExpressionFormula(id self, SEL cmd) { NSLog(@"call getExpressionFormula"); return nil; } 
  1. ID가 유형을 나타내는 @ V는 공백을 나타냅니다 표현 SEL의 유형을
  2. "V의 @는 @", 반환 값은 무효 나타내는 ID 유형, 유형 SEL, 타입 ID 방법을 허용
  3. "@@는": 리턴 값 ID의 타입을 나타내고, ID는 파라미터 타입 및 SEL 입력 방법을 허용

특정 세부 사항 런타임 런타임, 여기에 세부로 이동, 단순히 다음 런타임이 라인에 클래스에 속성과 메서드를 동적으로 추가 할 수 있습니다 이해하는 것이 아니다.

두, MJExtension 사용

방법의 MJExtension 구현의 대부분은 새로운 클래스를 사용하지 않고 분류에 통합되어, 당신은 단지 헤더 파일 MJExtension.h을 포함해야합니다. GitHub의에 MJExtension 지침은 매우 이해 썼다.

1. 간단한 사전 -> 모델

사용자 모델 클래스 정의 :

typedef enum {
    SexMale,
    SexFemale
} Sex;
@interface User : NSObject @property (copy, nonatomic) NSString *name;/* 姓名 */ @property (copy, nonatomic) NSString *icon;/* 头像 */ @property (assign, nonatomic) unsigned int age;/* 年龄 */ @property (copy, nonatomic) NSString *height;/* 身高 */ @property (strong, nonatomic) NSNumber *money;/* 资产 */ @property (assign, nonatomic) Sex sex;/* 性别 */ @property (assign, nonatomic, getter=isGay) BOOL gay;/* 是否是同性恋 */ @end 

예 :

NSDictionary *dict = @{
    @"name" : @"Jack",
    @"icon" : @"lufy.png",
    @"age" : @20, @"height" : @"1.55", @"money" : @100.9, @"sex" : @(SexFemale),/* 枚举需要使用NSNumber包装 */ @"gay" : @"NO" }; //字典转模型,使用的是mj_objectWithKeyValues:方法 User *user = [User mj_objectWithKeyValues:dict]; 

2. JSON 문자열 -> 모델

예 :

// 定义一个JSON字符串
NSString *jsonString = @"{\"name\":\"Jack\", \"icon\":\"lufy.png\", \"age\":20}";
// JSON字符串转模型
User *user = [User mj_objectWithKeyValues:jsonString];

3. 복잡한 사전 -> 모델 (모델을 포함 모델)

상태 모델 클래스 정의 :

@interface Status : NSObject
@property (copy, nonatomic) NSString *text; @property (strong, nonatomic) User *user;/* 其他模型类型 */ @property (strong, nonatomic) Status *retweetedStatus;/* 自我模型类型 */ @end 

예 :

NSDictionary *dict = @{
    @"text" : @"Agree!Nice weather!",
    @"user" : @{
        @"name" : @"Jack", @"icon" : @"lufy.png" }, @"retweetedStatus" : @{ @"text" : @"Nice weather!", @"user" : @{ @"name" : @"Rose", @"icon" : @"nami.png" } } }; //字典转模型,模型里面含有模型 Status *status = [Status mj_objectWithKeyValues:dict]; NSString *text = status.text; NSString *name = status.user.name; NSString *icon = status.user.icon; NSLog(@"text=%@, name=%@, icon=%@", text, name, icon); // text=Agree!Nice weather!, name=Jack, icon=lufy.png NSString *text2 = status.retweetedStatus.text; NSString *name2 = status.retweetedStatus.user.name; NSString *icon2 = status.retweetedStatus.user.icon; NSLog(@"text2=%@, name2=%@, icon2=%@", text2, name2, icon2); // text2=Nice weather!, name2=Rose, icon2=nami.png 

제 복잡한 사전 -> 모델 (모델 배열 속성 내부 모델 가득)

광고 및 StatusResult 모델 클래스 정의 :

@interface Ad : NSObject
@property (copy, nonatomic) NSString *image; @property (copy, nonatomic) NSString *url; @end @interface StatusResult : NSObject /** 数组中存储模型Status类型数据 */ @property (strong, nonatomic) NSMutableArray *statuses; /** 数组中存储模型Ad类型数据 */ @property (strong, nonatomic) NSArray *ads; @property (strong, nonatomic) NSNumber *totalNumber; @end #import "MJExtension.h" /* 数组中存储模型数据,需要说明数组中存储的模型数据类型 */ @implementation StatusResult /* 实现该方法,说明数组中存储的模型数据类型 */ + (NSDictionary *)mj_ objectClassInArray{ return @{ @"statuses" : @"Status", @"ads" : @"Ad" }; } @end 

예 :

NSDictionary *dict = @{
    @"text" : @"Agree!Nice weather!",
    @"user" : @{
        @"name" : @"Jack", @"icon" : @"lufy.png" }, @"retweetedStatus" : @{ @"text" : @"Nice weather!", @"user" : @{ @"name" : @"Rose", @"icon" : @"nami.png" } } }; //字典转模型,模型里面含有模型 Status *status = [Status mj_objectWithKeyValues:dict]; NSString *text = status.text; NSString *name = status.user.name; NSString *icon = status.user.icon; NSLog(@"text=%@, name=%@, icon=%@", text, name, icon); // text=Agree!Nice weather!, name=Jack, icon=lufy.png NSString *text2 = status.retweetedStatus.text; NSString *name2 = status.retweetedStatus.user.name; NSString *icon2 = status.retweetedStatus.user.icon; NSLog(@"text2=%@, name2=%@, icon2=%@", text2, name2, icon2); // text2=Nice weather!, name2=Rose, icon2=nami.png 

5. 복잡한 사전 -> 모델 (키 속성 이름과 모델 사전은 동일하지 않습니다)

가방 모델 클래스와 학생의 정의 :

@interface Bag : NSObject
@property (copy, nonatomic) NSString *name; @property (assign, nonatomic) double price; @end @interface Student : NSObject @property (copy, nonatomic) NSString *ID; @property (copy, nonatomic) NSString *desc; @property (copy, nonatomic) NSString *nowName; @property (copy, nonatomic) NSString *oldName; @property (copy, nonatomic) NSString *nameChangedTime; @property (strong, nonatomic) Bag *bag; @end #import "MJExtension.h" @implementation /* 设置模型属性名和字典key之间的映射关系 */ + (NSDictionary *)mj_replacedKeyFromPropertyName{ /* 返回的字典,key为模型属性名,value为转化的字典的多级key */ return @{ @"ID" : @"id", @"desc" : @"desciption", @"oldName" : @"name.oldName", @"nowName" : @"name.newName", @"nameChangedTime" : @"name.info[1].nameChangedTime", @"bag" : @"other.bag" }; } @end 

예 :

NSDictionary *dict = @{
    @"id" : @"20",
    @"desciption" : @"kids", @"name" : @{ @"newName" : @"lufy", @"oldName" : @"kitty", @"info" : @[ @"test-data", @{ @"nameChangedTime" : @"2013-08" } ] }, @"other" : @{ @"bag" : @{ @"name" : @"a red bag", @"price" : @100.7 } } }; //字典转模型,支持多级映射 Student *stu = [Student mj_objectWithKeyValues:dict]; //打印 NSLog(@"ID=%@, desc=%@, oldName=%@, nowName=%@, nameChangedTime=%@", stu.ID, stu.desc, stu.oldName, stu.nowName, stu.nameChangedTime); // ID=20, desc=kids, oldName=kitty, nowName=lufy, nameChangedTime=2013-08 NSLog(@"bagName=%@, bagPrice=%f", stu.bag.name, stu.bag.price); // bagName=a red bag, bagPrice=100.700000 

6. 어레이 사전 -> 모델 어레이

예 :

NSArray *dictArray = @[
                         @{
                             @"name" : @"Jack",
                             @"icon" : @"lufy.png" }, @{ @"name" : @"Rose", @"icon" : @"nami.png" } ]; //字典数组转模型数组,使用的是mj_objectArrayWithKeyValuesArray:方法 NSArray *userArray = [User mj_objectArrayWithKeyValuesArray:dictArray]; //打印 for (User *user in userArray) { NSLog(@"name=%@, icon=%@", user.name, user.icon); } // name=Jack, icon=lufy.png // name=Rose, icon=nami.png 

7. 모델 -> 사전

예 :

//创建一个模型对象
User *user = [[User alloc] init];
user.name = @"Jack";
user.icon = @"lufy.png";
Status *status = [[Status alloc] init];
status.user = user;
status.text = @"Nice mood!";
//模型转字典,使用的是mj_keyValues属性 NSDictionary *statusDict = status.mj_keyValues; NSLog(@"%@", statusDict); /* { text = "Nice mood!"; user = { icon = "lufy.png"; name = Jack; }; } */ 

8. 모델 어레이 -> 어레이 사전

예 :

//创建模型数组
User *user1 = [[User alloc] init];
user1.name = @"Jack";
user1.icon = @"lufy.png";
User *user2 = [[User alloc] init];
user2.name = @"Rose";
user2.icon = @"nami.png"; NSArray *userArray = @[user1, user2]; //模型数组转字典数组,使用的是mj_keyValuesArrayWithObjectArray:方法 NSArray *dictArray = [User mj_keyValuesArrayWithObjectArray:userArray]; NSLog(@"%@", dictArray); /* ( { icon = "lufy.png"; name = Jack; }, { icon = "nami.png"; name = Rose; } ) */ 

9. 사전 -> CoreData 모델

예 :

NSDictionary *dict = @{
                         @"name" : @"Jack",
                         @"icon" : @"lufy.png", @"age" : @20, @"height" : @1.55, @"money" : @"100.9", @"sex" : @(SexFemale), @"gay" : @"true" }; //字典转为CoreData模型 NSManagedObjectContext *context = nil; User *user = [User mj_objectWithKeyValues:dict context:context]; [context save:nil]; 

10. 제출 및 전개함으로써 NSCoding

모델 클래스 가방을 달성하기 위해 추가

@interface Bag : NSObject <NSCoding> @property (copy, nonatomic) NSString *name; @property (assign, nonatomic) double price; @end #import "MJExtension.h" @implementation Bag //添加了下面的宏定义 MJExtensionCodingImplementation /* 实现下面的方法,说明哪些属性不需要归档和解档 */ + (NSArray *)mj_ignoredCodingPropertyNames{ return @[@"name"]; } @end 

예 :

//创建模型
Bag *bag = [[Bag alloc] init];
bag.name = @"Red bag";
bag.price = 200.8;
//获取归档路径
NSString *file = [NSHomeDirectory() stringByAppendingPathComponent:@"Desktop/bag.data"]; //归档 [NSKeyedArchiver archiveRootObject:bag toFile:file]; //解档 Bag *decodedBag = [NSKeyedUnarchiver unarchiveObjectWithFile:file]; NSLog(@"name=%@, price=%f", decodedBag.name, decodedBag.price); // name=(null), price=200.800000 

사전 (11)의 필터 값

도서 모델 클래스를 달성 :

@interface Book: NSObject
@property (copy, nonatomic) NSString *name; @property (strong, nonatomic) NSDate *publishedTime; @end #import "MJExtension.h" @implementation Book /* 转化过程中对字典的值进行过滤和进一步转化 */ - (id)mj_newValueFromOldValue:(id)oldValue property:(MJProperty *)property { if ([property.name isEqualToString:@"publisher"]) { if (oldValue == nil) { return @""; } } else if (property.type.typeClass == [NSDate class]) { NSDateFormatter *fmt = [[NSDateFormatter alloc] init]; fmt.dateFormat = @"yyyy-MM-dd"; return [fmt dateFromString:oldValue]; } return oldValue; } @end 

예 :

NSDictionary *dict = @{
                       @"name" : @"5分钟突破iOS开发",
                       @"publishedTime" : @"2011-09-10" }; //字典转模型,过滤name为nil的情况,把NSString转为NSDate Book *book = [Book mj_objectWithKeyValues:dict]; //打印 NSLog(@"name=%@, publishedTime=%@", book.name, book.publishedTime); 

여기 Github의 포인트 MJExtension 주소 : CoderMJLee / MJExtension



저자 : 베일러 클래식
링크 : HTTPS : //www.jianshu.com/p/53ff148c6670
출처 : 제인 책
저자가 보유 제인 책의 저작권은, 어떤 형태로도 복제되어, 승인을 얻기 위해 작성자에게 문의하고 소스를 표시하시기 바랍니다.

추천

출처www.cnblogs.com/Acee/p/10930008.html