美文网首页
浅浅的解析---MJExtension

浅浅的解析---MJExtension

作者: TsingQue | 来源:发表于2017-05-09 17:58 被阅读202次
MJExtension.png

做一件事儿肯定是有原因,我来做这个事儿的原因,是因为我鹏哥思考需要在,路漫漫其修远兮,上下求索。

然后...鑫哥觉得,要成为大牛,首先要做的就是先跟大牛学习下,那么就抄一下大牛的代码吧...(我觉得很对)

一步一步走走看看,那么就先从我们最为常用的MJEX来入手,我也来copy一遍代码来试试

根据以前的样子,那么我先把目录写下来,然后进行一步一步一步的摩擦,且来看看👀👀

MJExtension

MJEX.png

引入头文件真的没什么可说的
MJExtension.h作为一个.h的头文件引入类,可谓是清新脱俗,简单明了 ...巴拉巴拉巴拉
然后下一步开始逐渐解析MJEX

MJExtensionConst

方法过期使用

#define MJExtensionDeprecated(instead) NS_DEPRECATED(2_0, 2_0, 2_0, 2_0, instead)
这个方法在设计库或者sdk的时候会使用到,然后标注显示

删除横线.png
具体使用的是如下方法
@property(nonatomic, copy)NSString *gdtype __attribute__((deprecated("已过期, 用goodsclassifytype替换")));

构建错误

#define MJExtensionBuildError(clazz, msg) \
NSError *error = [NSError errorWithDomain:msg code:250 userInfo:nil]; \
[clazz setMj_error:error];
NSError类里面的方法使用.png

其中,自定义错误域对象CustomErrorDomain,通常用域名反写,也可以是任何其他字符串code错误标识, 系统的code一般都大于零,自定code可以用枚举(最好用负数, 但不是必须的)userInfo自定义错误信息,NSLocalizedDescriptionKey是NSError头文件中预定义的键,标识错误的本地化描述

可以通过NSError的localizedDescription方法获得对应的值信息
详细介绍NSError的可以查看iphone跬步之--错误信息 NSError

日志输出

这一块代码没什么可以讲解的,就是log的打印

#ifdef DEBUG
#define MJExtensionLog(...) NSLog(__VA_ARGS__)
#else
#define MJExtensionLog(...)
#endif

使用
#define NSLog(fmt, ...) NSLog((@"%s [Line: %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
这个打印,会打印出你的类名方法名和对应的行数[当做平时的一个小知识来记忆吧~]

剩下的这一堆是断言的使用

/**
 * 断言
 * @param condition   条件
 * @param returnValue 返回值
 */
#define MJExtensionAssertError(condition, returnValue, clazz, msg) \
[clazz setMj_error:nil]; \
if ((condition) == NO) { \
    MJExtensionBuildError(clazz, msg); \
    return returnValue;\
}

#define MJExtensionAssert2(condition, returnValue) \
if ((condition) == NO) return returnValue;

/**
 * 断言
 * @param condition   条件
 */
#define MJExtensionAssert(condition) MJExtensionAssert2(condition, )

/**
 * 断言
 * @param param         参数
 * @param returnValue   返回值
 */
#define MJExtensionAssertParamNotNil2(param, returnValue) \
MJExtensionAssert2((param) != nil, returnValue)

/**
 * 断言
 * @param param   参数
 */
#define MJExtensionAssertParamNotNil(param) MJExtensionAssertParamNotNil2(param, )```
>断言:NSAssert()是一个宏,用于开发阶段调试程序中的Bug,通过为NSAssert()传递条件表达式来断定是否属于Bug,满足条件返回真值,程序继续运行,如果返回假值,则抛出异常,并且可以自定义异常描述。
这里引用下别人对于[断言的介绍](http://www.jianshu.com/p/6e444981ab45)

MJEX将打印所有的属性使用宏定义在Const里面写出,为了可以在全局中方便的调用

/**

  • 打印所有的属性
    */

define MJLogAllIvars \

-(NSString *)description
{
return [self mj_keyValues].description;
}

define MJExtensionLogAllProperties MJLogAllIvars

直接调用`MJLogAllIvars `的宏定义就可以直接输出所有属性

类属性的使用 

/**

  • 类型(属性类型)
    */
    extern NSString *const MJPropertyTypeInt;
    extern NSString *const MJPropertyTypeShort;
    extern NSString *const MJPropertyTypeFloat;
    extern NSString *const MJPropertyTypeDouble;
    extern NSString *const MJPropertyTypeLong;
    extern NSString *const MJPropertyTypeLongLong;
    extern NSString *const MJPropertyTypeChar;
    extern NSString *const MJPropertyTypeBOOL1;
    extern NSString *const MJPropertyTypeBOOL2;
    extern NSString *const MJPropertyTypePointer;

extern NSString *const MJPropertyTypeIvar;
extern NSString *const MJPropertyTypeMethod;
extern NSString *const MJPropertyTypeBlock;
extern NSString *const MJPropertyTypeClass;
extern NSString *const MJPropertyTypeSEL;
extern NSString *const MJPropertyTypeId;

从这个类属性里面,我们可以清楚的了解到MJEX对于某些类的拓展使用

/**

  • 成员变量类型(属性类型)
    */
    NSString *const MJPropertyTypeInt = @"i";
    NSString *const MJPropertyTypeShort = @"s";
    NSString *const MJPropertyTypeFloat = @"f";
    NSString *const MJPropertyTypeDouble = @"d";
    NSString *const MJPropertyTypeLong = @"l";
    NSString *const MJPropertyTypeLongLong = @"q";
    NSString *const MJPropertyTypeChar = @"c";
    NSString *const MJPropertyTypeBOOL1 = @"c";
    NSString *const MJPropertyTypeBOOL2 = @"b";
    NSString const MJPropertyTypePointer = @"";

NSString *const MJPropertyTypeIvar = @"^{objc_ivar=}";
NSString *const MJPropertyTypeMethod = @"^{objc_method=}";
NSString *const MJPropertyTypeBlock = @"@?";
NSString *const MJPropertyTypeClass = @"#";
NSString *const MJPropertyTypeSEL = @":";
NSString *const MJPropertyTypeId = @"@";

【借鉴】对于.m里面的赋值,从而借鉴可以从编辑全局的某些text或者Toast的信息可以使用上方式作为统一的管理:
例如
.h
`extern NSString *const MJToast_Success;`
.m
`NSString *const MJToast_Success  = @"保存成功"`
从而在全局统一使用

##MJFoundation
继承自`@interface MJFoundation : NSObject`只用一个方法
`+ (BOOL)isClassFromFoundation:(Class)c;`
>MJ是这样注释的----
集合中没有NSObject,因为几乎所有的类都是继承自NSObject,具体是不是NSObject需要特殊判断

![使用NSSet将数据的不属于NSObj的类加入.png](https://img.haomeiwen.com/i693139/25f36e7cfb54e302.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

>【注意】NSSet和NSMutableSet是无序的!!!!看准咯是无序的!因为它本身的排序是使用的哈希排序(划重点)
而且他是唯一的!!里面的每一个数据都是唯一的!!!!(划重点)
之前我遇到的问题也是如此,讨厌于双重for循环去去重,直接使用了NSMutableSet,但是没有注意到是无序的序列,对于需要排序的,建议写一个字段排序的方法,这里不再做赘述


##MJProperty -- 包装一个成员属性
关于如何包装一个成员属性呢,那么我们先看一下MJ如何去做的
`/** 成员属性 */
@property (nonatomic, assign) objc_property_t property;`
> objc_property_t 
···what is this?
[iOS反射机制: objc_property_t的使用](https://segmentfault.com/a/1190000004520289)
这为大哥写的蛮详细,这里做简略的介绍
 `/// An opaque type that represents an Objective-C declared property.
typedef struct objc_property *objc_property_t;`
apple将其称为一个隐藏的类型,OC中的一个声明属性。

>iOS属性反射:说白了,就是将两个对象的所有属性,用动态的方式取出来,并根据属性名,自动绑值。(注意:对象的类,如果是派生类,就得靠其他方式来实现了,因为得到不该基类的属性。)

常用的反射方式,有如下两种:


>2-从一个NSDictionary->自定义实体类(此方式最最常用,如网络Json数据会组成NSDictionary。sqlite查询数据,可以用第三方组件组成NSDictionary)
直接上码,(这里码在NSObject类别中)
获取对象所有属性:

我注意到MJEX使用了这样一个属性---[关联](http://blog.csdn.net/onlyou930/article/details/9299169)

![关联属性-MJEX.png](https://img.haomeiwen.com/i693139/5f145a81a8f9ee75.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

这个类的核心代码如下,我么一段一段进行解析
// 通过字符串key创建对应的keys
```objective-c
 - (NSArray *)propertyKeysWithStringKey:(NSString *)stringKey
    {
        if (stringKey.length == 0) return nil;
        
        NSMutableArray *propertyKeys = [NSMutableArray array];
        // 如果有多级映射
        NSArray *oldKeys = [stringKey componentsSeparatedByString:@"."];
        
        for (NSString *oldKey in oldKeys) {
            NSUInteger start = [oldKey rangeOfString:@"["].location;
            if (start != NSNotFound) { // 有索引的key
                NSString *prefixKey = [oldKey substringToIndex:start];
                NSString *indexKey = prefixKey;
                if (prefixKey.length) {
                    MJPropertyKey *propertyKey = [[MJPropertyKey alloc] init];
                    propertyKey.name = prefixKey;
                    [propertyKeys addObject:propertyKey];
                    
                    indexKey = [oldKey stringByReplacingOccurrencesOfString:prefixKey withString:@""];
                }
                
                /** 解析索引 **/
                // 元素
                NSArray *cmps = [[indexKey stringByReplacingOccurrencesOfString:@"[" withString:@""] componentsSeparatedByString:@"]"];
                for (NSInteger i = 0; i<cmps.count - 1; i++) {
                    MJPropertyKey *subPropertyKey = [[MJPropertyKey alloc] init];
                    subPropertyKey.type = MJPropertyKeyTypeArray;
                    subPropertyKey.name = cmps[i];
                    [propertyKeys addObject:subPropertyKey];
                }
            } else { // 没有索引的key
                MJPropertyKey *propertyKey = [[MJPropertyKey alloc] init];
                propertyKey.name = oldKey;
                [propertyKeys addObject:propertyKey];
            }
        }
        
        return propertyKeys;
    }

采用多级映射的方式,将对应的关联key值进行

MJPropertyKey

MJPropertyType

NSObject+MJClass

NSObject+MJCoding

NSObject+MJKeyValue

NSObject+MJProperty

NSString+MJExtension

相关文章

  • 浅浅的解析---MJExtension

    做一件事儿肯定是有原因,我来做这个事儿的原因,是因为我鹏哥思考需要在,路漫漫其修远兮,上下求索。 然后...鑫哥觉...

  • MJExtension使用指导(转)

    1. MJExtension使用指导(最新)2. MJExtension[模型字典]包含[模型字典数组]解析数据的...

  • MJExtension的几种用法

    这次研究下MJExtension,MJExtension是解析json的三方框架,简单实用下面是几种用法 最简单的...

  • 多线程网络05

    1 JSON解析代码 1.1 JSON -> OC 1.2 OC -> JSON 2 MJExtension 2....

  • MJExtension源码解析

    A fast, convenient and nonintrusive conversion between JS...

  • MJExtension源码解析

    核心代码 获取对象的每一个属性,包括父类的属性,不包括NSObject,代码如下 取出属性值,代码如下 对象类型的...

  • MJExtension源码解析

    前篇我们对 Runtime 的相关方法进行了总结,同时也响应了写了几个案例,这次为了巩固下知识点,这里研究并分析了...

  • 软件开发数据解析思路

    标准的数据解析: 什么是ResponseModel:对服务端下发数据的全量解析,使用第三方库MJExtension...

  • 字符串包含数组json解析

    今天拿到后台返回的一组数据,解析成一个数组的模型,记录一下。先说数据吧 解析 不知道MJExtension能否解析...

  • 网络结果解析库毛皮之谈

    市面上解决数据解析这块非常多方案 json解析上oc中mjextension yymodel 什么的都不说了不是说...

网友评论

      本文标题:浅浅的解析---MJExtension

      本文链接:https://www.haomeiwen.com/subject/rtjitxtx.html