淺淺的解析---MJExtension

MJExtension.png

做一件事兒肯定是有原因,我來做這個(gè)事兒的原因,是因?yàn)槲淫i哥思考需要在沪编,路漫漫其修遠(yuǎn)兮呼盆,上下求索。

然后...鑫哥覺得蚁廓,要成為大牛访圃,首先要做的就是先跟大牛學(xué)習(xí)下,那么就抄一下大牛的代碼吧...(我覺得很對(duì))

一步一步走走看看相嵌,那么就先從我們最為常用的MJEX來入手腿时,我也來copy一遍代碼來試試

根據(jù)以前的樣子,那么我先把目錄寫下來饭宾,然后進(jìn)行一步一步一步的摩擦批糟,且來看看????

MJExtension

MJEX.png

引入頭文件真的沒什么可說的
MJExtension.h作為一個(gè).h的頭文件引入類,可謂是清新脫俗看铆,簡(jiǎn)單明了 ...巴拉巴拉巴拉
然后下一步開始逐漸解析MJEX

MJExtensionConst

方法過期使用

#define MJExtensionDeprecated(instead) NS_DEPRECATED(2_0, 2_0, 2_0, 2_0, instead)
這個(gè)方法在設(shè)計(jì)庫或者sdk的時(shí)候會(huì)使用到徽鼎,然后標(biāo)注顯示

刪除橫線.png

具體使用的是如下方法
@property(nonatomic, copy)NSString *gdtype __attribute__((deprecated("已過期, 用goodsclassifytype替換")));

構(gòu)建錯(cuò)誤

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

其中,自定義錯(cuò)誤域?qū)ο驝ustomErrorDomain弹惦,通常用域名反寫否淤,也可以是任何其他字符串code錯(cuò)誤標(biāo)識(shí), 系統(tǒng)的code一般都大于零,自定code可以用枚舉(最好用負(fù)數(shù), 但不是必須的)userInfo自定義錯(cuò)誤信息棠隐,NSLocalizedDescriptionKey是NSError頭文件中預(yù)定義的鍵石抡,標(biāo)識(shí)錯(cuò)誤的本地化描述

可以通過NSError的localizedDescription方法獲得對(duì)應(yīng)的值信息
詳細(xì)介紹NSError的可以查看iphone跬步之--錯(cuò)誤信息 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__)
這個(gè)打印,會(huì)打印出你的類名方法名和對(duì)應(yīng)的行數(shù)[當(dāng)做平時(shí)的一個(gè)小知識(shí)來記憶吧~]

剩下的這一堆是斷言的使用

/**
 * 斷言
 * @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         參數(shù)
 * @param returnValue   返回值
 */
#define MJExtensionAssertParamNotNil2(param, returnValue) \
MJExtensionAssert2((param) != nil, returnValue)

/**
 * 斷言
 * @param param   參數(shù)
 */
#define MJExtensionAssertParamNotNil(param) MJExtensionAssertParamNotNil2(param, )```
>斷言:NSAssert()是一個(gè)宏助泽,用于開發(fā)階段調(diào)試程序中的Bug汁雷,通過為NSAssert()傳遞條件表達(dá)式來斷定是否屬于Bug,滿足條件返回真值报咳,程序繼續(xù)運(yùn)行侠讯,如果返回假值,則拋出異常暑刃,并且可以自定義異常描述厢漩。
這里引用下別人對(duì)于[斷言的介紹](http://www.reibang.com/p/6e444981ab45)

MJEX將打印所有的屬性使用宏定義在Const里面寫出,為了可以在全局中方便的調(diào)用

/**

  • 打印所有的屬性
    */

define MJLogAllIvars \

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

define MJExtensionLogAllProperties MJLogAllIvars

直接調(diào)用`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;

從這個(gè)類屬性里面岩臣,我們可以清楚的了解到MJEX對(duì)于某些類的拓展使用

/**

  • 成員變量類型(屬性類型)
    */
    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 = @"@";

【借鑒】對(duì)于.m里面的賦值溜嗜,從而借鑒可以從編輯全局的某些text或者Toast的信息可以使用上方式作為統(tǒng)一的管理:
例如
.h
`extern NSString *const MJToast_Success;`
.m
`NSString *const MJToast_Success  = @"保存成功"`
從而在全局統(tǒng)一使用

##MJFoundation
繼承自`@interface MJFoundation : NSObject`只用一個(gè)方法
`+ (BOOL)isClassFromFoundation:(Class)c;`
>MJ是這樣注釋的----
集合中沒有NSObject,因?yàn)閹缀跛械念惗际抢^承自NSObject架谎,具體是不是NSObject需要特殊判斷

![使用NSSet將數(shù)據(jù)的不屬于NSObj的類加入.png](http://upload-images.jianshu.io/upload_images/693139-25f36e7cfb54e302.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

>【注意】NSSet和NSMutableSet是無序的!!!!看準(zhǔn)咯是無序的炸宵!因?yàn)樗旧淼呐判蚴鞘褂玫墓E判颍▌澲攸c(diǎn))
而且他是唯一的!谷扣!里面的每一個(gè)數(shù)據(jù)都是唯一的M寥I铀觥!9住(劃重點(diǎn))
之前我遇到的問題也是如此瑞凑,討厭于雙重for循環(huán)去去重,直接使用了NSMutableSet概页,但是沒有注意到是無序的序列籽御,對(duì)于需要排序的,建議寫一個(gè)字段排序的方法惰匙,這里不再做贅述


##MJProperty -- 包裝一個(gè)成員屬性
關(guān)于如何包裝一個(gè)成員屬性呢技掏,那么我們先看一下MJ如何去做的
`/** 成員屬性 */
@property (nonatomic, assign) objc_property_t property;`
> objc_property_t 
···what is this?
[iOS反射機(jī)制: objc_property_t的使用](https://segmentfault.com/a/1190000004520289)
這為大哥寫的蠻詳細(xì)项鬼,這里做簡(jiǎn)略的介紹
 `/// An opaque type that represents an Objective-C declared property.
typedef struct objc_property *objc_property_t;`
apple將其稱為一個(gè)隱藏的類型哑梳,OC中的一個(gè)聲明屬性。

>iOS屬性反射:說白了秃臣,就是將兩個(gè)對(duì)象的所有屬性涧衙,用動(dòng)態(tài)的方式取出來哪工,并根據(jù)屬性名奥此,自動(dòng)綁值。(注意:對(duì)象的類雁比,如果是派生類稚虎,就得靠其他方式來實(shí)現(xiàn)了,因?yàn)榈玫讲辉摶惖膶傩再松印#?
常用的反射方式蠢终,有如下兩種:


>2-從一個(gè)NSDictionary->自定義實(shí)體類(此方式最最常用,如網(wǎng)絡(luò)Json數(shù)據(jù)會(huì)組成NSDictionary茴她。sqlite查詢數(shù)據(jù)寻拂,可以用第三方組件組成NSDictionary)
直接上碼,(這里碼在NSObject類別中)
獲取對(duì)象所有屬性:

我注意到MJEX使用了這樣一個(gè)屬性---[關(guān)聯(lián)](http://blog.csdn.net/onlyou930/article/details/9299169)

![關(guān)聯(lián)屬性-MJEX.png](http://upload-images.jianshu.io/upload_images/693139-5f145a81a8f9ee75.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

這個(gè)類的核心代碼如下丈牢,我么一段一段進(jìn)行解析
// 通過字符串key創(chuàng)建對(duì)應(yīng)的keys
```objective-c
 - (NSArray *)propertyKeysWithStringKey:(NSString *)stringKey
    {
        if (stringKey.length == 0) return nil;
        
        NSMutableArray *propertyKeys = [NSMutableArray array];
        // 如果有多級(jí)映射
        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;
    }

采用多級(jí)映射的方式祭钉,將對(duì)應(yīng)的關(guān)聯(lián)key值進(jìn)行

MJPropertyKey

MJPropertyType

NSObject+MJClass

NSObject+MJCoding

NSObject+MJKeyValue

NSObject+MJProperty

NSString+MJExtension

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市己沛,隨后出現(xiàn)的幾起案子慌核,更是在濱河造成了極大的恐慌,老刑警劉巖申尼,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件垮卓,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡师幕,警方通過查閱死者的電腦和手機(jī)粟按,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人钾怔,你說我怎么就攤上這事碱呼。” “怎么了宗侦?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵愚臀,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我矾利,道長(zhǎng)姑裂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任男旗,我火速辦了婚禮舶斧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘察皇。我一直安慰自己茴厉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布什荣。 她就那樣靜靜地躺著矾缓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪稻爬。 梳的紋絲不亂的頭發(fā)上嗜闻,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音桅锄,去河邊找鬼琉雳。 笑死,一個(gè)胖子當(dāng)著我的面吹牛友瘤,可吹牛的內(nèi)容都是我干的翠肘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼辫秧,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼束倍!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起茶没,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤肌幽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后抓半,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體喂急,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年笛求,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了廊移。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片糕簿。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖狡孔,靈堂內(nèi)的尸體忽然破棺而出懂诗,到底是詐尸還是另有隱情,我是刑警寧澤苗膝,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布殃恒,位于F島的核電站,受9級(jí)特大地震影響辱揭,放射性物質(zhì)發(fā)生泄漏离唐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一问窃、第九天 我趴在偏房一處隱蔽的房頂上張望亥鬓。 院中可真熱鬧,春花似錦域庇、人聲如沸嵌戈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽熟呛。三九已至,卻和暖如春写穴,著一層夾襖步出監(jiān)牢的瞬間惰拱,已是汗流浹背雌贱。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工啊送, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人欣孤。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓馋没,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親降传。 傳聞我的和親對(duì)象是個(gè)殘疾皇子篷朵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,709評(píng)論 0 9
  • 你有沒有一個(gè)無法靠近的人婆排? 為了靠近他声旺,你想盡辦法,用盡心思段只,最后只得到一個(gè)過分熱情的結(jié)論腮猖,你毫無反抗之力,也無從...
    花田夜語閱讀 487評(píng)論 0 1
  • 你是不是經(jīng)常在領(lǐng)導(dǎo)面前或者公眾面前說話時(shí)有一種身體被扭曲赞枕,手舞足蹈澈缺,不知如何安放自己的雙手坪创,恨不得把自己雙手砍掉的...
    小叮當(dāng)在哪里閱讀 1,010評(píng)論 0 1
  • 有人問:“我喜歡的女孩子莱预,不理我了,本來她跟我無話不說的……算了项滑,我也給不了她什么依沮,還是放棄吧……我也累了,不打擾...
    司馬香老師閱讀 275評(píng)論 0 1