ReactNative源碼筆記——你知道幾條慈鸠?

轉(zhuǎn)載請注明出處:http://www.olinone.com/

ReactNative是Facebook開源的一種實現(xiàn)移動跨平臺開發(fā)的解決方案逝段,目前在業(yè)界得到廣泛應(yīng)用私股,這里有非常詳細的中文使用指南刷允。本文主要分享RN源碼中一些值得大家學(xué)習(xí)或者借鑒的代碼或者編寫技巧等冤留,供大家學(xué)習(xí)參考

整個RN庫包含10多個工程,有興趣的童鞋可以下載源碼查看具體細節(jié)树灶,在此不再展開

宏定義巧用

整個ReactNative源碼工程中用到了大量的宏定義纤怒,包括RCT_EXTERN、RCT_NOT_IMPLEMENTED破托、RCT_EXPORT_METHOD以及RCT_EXPORT_MODULE等申明宏或者功能宏肪跋。通過宏定義的方式,可以非常方便嵌入功能代碼或者邏輯實現(xiàn)土砂,重用代碼的同時又保持了代碼的整潔性

比如州既,ProtocolKit工程中谜洽,作者通過宏定義@defs將Protocol接口巧妙的實現(xiàn)在.h文件中,代碼簡介明了吴叶,又不失功能完整性阐虚。當(dāng)然,RN工程中蚌卤,RCT_NOT_IMPLEMENTED宏也有相似作用实束,實際項目中各位也可以嘗試通過宏定義實現(xiàn)一些常用功能模塊

關(guān)于iOS宏定義的文章有很多,在此推薦兩篇非常不錯的文章:RAC中必須要知道的宏逊彭、ios宏的使用和技巧

環(huán)境變量

iOS開發(fā)中咸灿,各位對#ifdef DEBUG應(yīng)該非常熟悉,通過判斷該條件侮叮,可以區(qū)別當(dāng)前運行環(huán)境是Debug環(huán)境還是Release環(huán)境避矢。比如Release環(huán)境下通過重定義NSLog以屏蔽所有日志輸出

#ifdef DEBUG

#define NSLog(...) NSLog(__VA_ARGS__)

#else

#define NSLog(...) {}

#endif

進一步,是否可以考慮只在聯(lián)機調(diào)試環(huán)境下輸出日志囊榜?此時就涉及聯(lián)機調(diào)試環(huán)境的判斷审胸,環(huán)境變量正好可以解決該問題

Xcode可以在不同環(huán)境下自定義環(huán)境變量Environment Variables,通過在運行環(huán)境Run中自定義變量CI_USE_PACKAGER卸勺,此時便可在項目代碼中通過getenv()函數(shù)判斷當(dāng)前運行環(huán)境

if (getenv("CI_USE_PACKAGER")) {

? ? // to do...

}

被忽略的硬鍵盤

相較于軟鍵盤文字符號的輸入砂沛,對于APP來說,硬鍵盤的應(yīng)用開發(fā)似乎很容易被忽視曙求,畢竟碍庵,通常情況下,硬鍵盤輸入只會出現(xiàn)在模擬器環(huán)境下

iOS7以后圆到,系統(tǒng)定義有硬鍵盤響應(yīng)交互類UIKeyCommand怎抛,通過UIKeyCommand,APP能夠監(jiān)聽硬鍵盤的特定輸入響應(yīng)芽淡,比如Command+D等马绝,當(dāng)然,前提是APP需要首先監(jiān)聽該輸入命令

UIKeyCommand的使用非常簡單挣菲,當(dāng)需要在特定場景觸發(fā)某一事件富稻,但又不想影響界面顯示的時候,不妨試試UIKeyCommand白胀,具體使用可以看看這篇文章

_cmd

iOS官方文檔中椭赋,_cmd表示當(dāng)前方法的selector,你可以通過下面代碼打印輸出當(dāng)前函數(shù)名

NSLog(@"Current method: %@", NSStringFromSelector(_cmd));

當(dāng)然或杠,實際項目中哪怔,你也可以這樣使用

NSNumber *rootTag = objc_getAssociatedObject(self, _cmd) ?: @1;

objc_setAssociatedObject(self, _cmd, @(rootTag.integerValue + 10), OBJC_ASSOCIATION_RETAIN_NONATOMIC);

瞧,是不是有點意思!

kCFNull

相對于nil NSNull而言认境,kCFNull筆者接觸較少胚委,kCFNull可以理解為NSNull單例對象

id null1 = (id)kCFNull;

id null2 = [NSNull null];

打印地址

null1=(NSNull *)0x10426eaf0

null2=(NSNull *)0x10426eaf0

從上面測試結(jié)果可以看出它們其實指向同一地址, 可以簡單理解為 kCFNull === [NSNull null]

文本陰影NSShadow

APP開發(fā)中叉信,程序猿可能經(jīng)常需要在圖片或視頻上顯示文字亩冬,由于背景顏色跟文字顏色相近,導(dǎo)致文字看不清硼身,比如時下火熱的直播彈幕顯示硅急,為了確保文字顯示清晰,開發(fā)者一般會配上陰影或者文字描邊

給文本添加陰影描邊佳遂,系統(tǒng)提供有NSShadow類营袜,可以這樣使用

NSShadow *shadow = [NSShadow new];

shadow.shadowOffset = CGSizeZero;

shadow.shadowBlurRadius = 5.0f;

shadow.shadowColor = [UIColor colorWithWhite:0.0f alpha:0.3f];

NSAttributedString *attString = [[NSAttributedString alloc] initWithString:@"www.olinone.com" attributes:@{NSShadowAttributeName: shadow, NSForegroundColorAttributeName: [UIColor whiteColor]}];

lbl.attributedText = attString;

實際效果是這樣的,shadowBlurRadius值越小讶迁,文本描邊越清晰

主線程判斷

判斷當(dāng)前執(zhí)行線程是否為主線程的方法有很多连茧,比如

[NSThread isMainThread]

pthread_main_np

在RN中,它是這樣的

BOOL RCTIsMainQueue() {

? ? ? static void *mainQueueKey = &mainQueueKey;

? ? ? static dispatch_once_t onceToken;

? ? ? dispatch_once(&onceToken, ^{

? ? ? ? ? dispatch_queue_set_specific(dispatch_get_main_queue(), mainQueueKey, mainQueueKey, NULL);

? });

? ? ? return dispatch_get_specific(mainQueueKey) == mainQueueKey;

}

當(dāng)然巍糯,由于無法查看NSThread內(nèi)部實現(xiàn)機制,暫時無法了解孰優(yōu)孰劣客扎,不過祟峦,[NSThread isMainThread]貌似足矣!

volatile不簡單

百科中徙鱼,是這樣描述它的:就像大家更熟悉的const一樣宅楞,volatile是一個類型修飾符,它是被設(shè)計用來修飾被不同線程訪問和修改的變量袱吆。作為指令關(guān)鍵字厌衙,確保本條指令不會因編譯器的優(yōu)化而省略,且要求每次直接讀值

簡單說绞绒,被volatile修飾的變量是多線程安全的婶希,其次,不會因為編譯器優(yōu)化導(dǎo)致讀值出錯蓬衡。關(guān)于編譯器編譯優(yōu)化可以看看這篇文章

iOS開發(fā)中確保多線程安全的方法有很多喻杈,原子操作、線程鎖狰晚、單線程執(zhí)行等等筒饰,本人也寫過相關(guān)文章iOS開發(fā)多線程同步

在RN中,通過volatile修飾符壁晒,巧妙實現(xiàn)了多線程取消操作

__block volatile uint32_t cancelled = 0;

if (!cancelled) {

? ? // to do...

}

OSAtomicOr32Barrier(1, &cancelled);

通過原子性操作訪問被volatile修飾的cancelled對象即可保障函數(shù)只執(zhí)行一次瓷们。想想大家熟悉的單例dispatch_once_t,現(xiàn)在讓你設(shè)計單例對象,你又會如何設(shè)計了谬晕?

+ (instancetype)sharedInstance {

? ? static RCTWebSocketManager *sharedInstance = nil;

? ? static dispatch_once_t onceToken;

? ? dispatch_once(&onceToken, ^{

? ? ? ? sharedInstance = [self new];

? ? });

? ? return sharedInstance;

}

結(jié)構(gòu)體Struct

說起Struct式镐,不知各位對它印象如何?大學(xué)C課本中學(xué)過固蚤?NSObject類class原型貌似有講娘汞?

struct iOSDev {

? ? NSString *nickName;

};

OC中一個簡單的結(jié)構(gòu)體,在Swift中夕玩,Struct也可以這樣寫

struct iOSDev {

? ? var nickName : String

? ? func getBusinessCard() -> String {

? ? ? ? return "\(nickName)你弦,幽默的iOS開發(fā)者!"

? ? }

};

let iOSOlinone = iOSDev(nickName: "olinone")

print(iOSOlinone.getBusinessCard())

getBusinessCard為結(jié)構(gòu)體函數(shù)燎孟,是不是感覺很方便禽作!其實OC中也可以這樣寫

struct iOSDev {

? ? NSString *nickName;

? ? NSString *getBusinessCard() {

? ? ? ? return [NSString stringWithFormat:@"%@,幽默的iOS開發(fā)者揩页!", nickName];

? ? }

};

iOSDev iosDev = iOSDev{@"olinone"};

NSLog(@"%@", iosDev.getBusinessCard());

當(dāng)然旷偿,為Struct添加函數(shù)并不是C語言特性,而是C++特性爆侣,因此萍程,為了編譯通過,你需要將.m文件修改成.mm文件

Struct有其使用的特殊場景兔仰,相較于Class茫负,合理的使用Struct可以使代碼更加整潔。同時乎赴,為了適應(yīng)Swift中Struct強大特性忍法,可以試著在OC項目中嘗試Struct

最后,給大家來個段子吧:

話說一美女要在兩個男人之間做選擇榕吼,一個年紀大饿序,長的丑,是個千萬富翁羹蚣,另一個年輕原探,帥氣,iOS開發(fā)程序猿度宦。 她對他們說踢匣,我會給你們一人一張紙條,寫著我愿意的那張就是我的選擇戈抄。 富翁打開紙條离唬,看見上面寫著我愿意,于是摟著她划鸽,坐上豪車高興的走了输莺。 年輕的小伙很傷心戚哎,打開紙條看見上面寫著:“等我一個月~” ?^o^


寫在文后:

有些童鞋可能經(jīng)常會問一個問題,感覺自己技術(shù)遇到瓶頸嫂用,如何才能進一步提升自己技術(shù)能力型凳?其實這個問題,本人也是摸石頭過河嘱函,不過有一點可以確定甘畅,那就是保持一顆不斷進取的心吧

新建了一個iOS開發(fā)QQ交流群(首頁右上角入群),歡迎廣大iOS開發(fā)朋友一同交流學(xué)習(xí)往弓。當(dāng)然疏唾,你也可以Follow本人GitHub,或者關(guān)注我的新浪微博函似,感謝你的來訪槐脏,下期再見!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末撇寞,一起剝皮案震驚了整個濱河市顿天,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蔑担,老刑警劉巖牌废,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異钟沛,居然都是意外死亡畔规,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門恨统,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人三妈,你說我怎么就攤上這事畜埋。” “怎么了畴蒲?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵悠鞍,是天一觀的道長。 經(jīng)常有香客問我模燥,道長咖祭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任蔫骂,我火速辦了婚禮么翰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘辽旋。我一直安慰自己浩嫌,他們只是感情好檐迟,可當(dāng)我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著码耐,像睡著了一般追迟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上骚腥,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天敦间,我揣著相機與錄音,去河邊找鬼束铭。 笑死廓块,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的纯露。 我是一名探鬼主播剿骨,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼埠褪!你這毒婦竟也來了浓利?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤钞速,失蹤者是張志新(化名)和其女友劉穎贷掖,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體渴语,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡苹威,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了驾凶。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片牙甫。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖调违,靈堂內(nèi)的尸體忽然破棺而出窟哺,到底是詐尸還是另有隱情,我是刑警寧澤技肩,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布且轨,位于F島的核電站,受9級特大地震影響虚婿,放射性物質(zhì)發(fā)生泄漏旋奢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一然痊、第九天 我趴在偏房一處隱蔽的房頂上張望至朗。 院中可真熱鬧,春花似錦玷过、人聲如沸爽丹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽粤蝎。三九已至叠赐,卻和暖如春撤蚊,著一層夾襖步出監(jiān)牢的瞬間非凌,已是汗流浹背橘霎。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留碑宴,地道東北人软啼。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像延柠,于是被迫代替她去往敵國和親祸挪。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,828評論 2 345

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

  • 史上最全的iOS面試題及答案 iOS面試小貼士———————————————回答好下面的足夠了----------...
    Style_偉閱讀 2,345評論 0 35
  • iOS面試小貼士 ———————————————回答好下面的足夠了------------------------...
    不言不愛閱讀 1,962評論 0 7
  • 多線程贞间、特別是NSOperation 和 GCD 的內(nèi)部原理贿条。運行時機制的原理和運用場景。SDWebImage的原...
    LZM輪回閱讀 2,004評論 0 12
  • ———————————————回答好下面的足夠了---------------------------------...
    恒愛DE問候閱讀 1,712評論 0 4
  • __block和__weak修飾符的區(qū)別其實是挺明顯的:1.__block不管是ARC還是MRC模式下都可以使用增热,...
    LZM輪回閱讀 3,284評論 0 6