ReactNative源码笔记——你知道几条?

转载请注明出处:http://www.olinone.com/

ReactNative是Facebook开源的一种实现移动跨平台开发的解决方案,目前在业界得到广泛应用,这里有非常详细的中文使用指南。本文主要分享RN源码中一些值得大家学习或者借鉴的代码或者编写技巧等,供大家学习参考

整个RN库包含10多个工程,有兴趣的童鞋可以下载源码查看具体细节,在此不再展开

宏定义巧用

整个ReactNative源码工程中用到了大量的宏定义,包括RCT_EXTERN、RCT_NOT_IMPLEMENTED、RCT_EXPORT_METHOD以及RCT_EXPORT_MODULE等申明宏或者功能宏。通过宏定义的方式,可以非常方便嵌入功能代码或者逻辑实现,重用代码的同时又保持了代码的整洁性

比如,ProtocolKit工程中,作者通过宏定义@defs将Protocol接口巧妙的实现在.h文件中,代码简介明了,又不失功能完整性。当然,RN工程中,RCT_NOT_IMPLEMENTED宏也有相似作用,实际项目中各位也可以尝试通过宏定义实现一些常用功能模块

关于iOS宏定义的文章有很多,在此推荐两篇非常不错的文章:RAC中必须要知道的宏ios宏的使用和技巧

环境变量

iOS开发中,各位对#ifdef DEBUG应该非常熟悉,通过判断该条件,可以区别当前运行环境是Debug环境还是Release环境。比如Release环境下通过重定义NSLog以屏蔽所有日志输出

#ifdef DEBUG

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

#else

#define NSLog(...) {}

#endif

进一步,是否可以考虑只在联机调试环境下输出日志?此时就涉及联机调试环境的判断,环境变量正好可以解决该问题

Xcode可以在不同环境下自定义环境变量Environment Variables,通过在运行环境Run中自定义变量CI_USE_PACKAGER,此时便可在项目代码中通过getenv()函数判断当前运行环境

if (getenv("CI_USE_PACKAGER")) {

    // to do...

}

被忽略的硬键盘

相较于软键盘文字符号的输入,对于APP来说,硬键盘的应用开发似乎很容易被忽视,毕竟,通常情况下,硬键盘输入只会出现在模拟器环境下

iOS7以后,系统定义有硬键盘响应交互类UIKeyCommand,通过UIKeyCommand,APP能够监听硬键盘的特定输入响应,比如Command+D等,当然,前提是APP需要首先监听该输入命令

UIKeyCommand的使用非常简单,当需要在特定场景触发某一事件,但又不想影响界面显示的时候,不妨试试UIKeyCommand,具体使用可以看看这篇文章

_cmd

iOS官方文档中,_cmd表示当前方法的selector,你可以通过下面代码打印输出当前函数名

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

当然,实际项目中,你也可以这样使用

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

从上面测试结果可以看出它们其实指向同一地址, 可以简单理解为 kCFNull === [NSNull null]

文本阴影NSShadow

APP开发中,程序猿可能经常需要在图片或视频上显示文字,由于背景颜色跟文字颜色相近,导致文字看不清,比如时下火热的直播弹幕显示,为了确保文字显示清晰,开发者一般会配上阴影或者文字描边

给文本添加阴影描边,系统提供有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值越小,文本描边越清晰

主线程判断

判断当前执行线程是否为主线程的方法有很多,比如

[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;

}

当然,由于无法查看NSThread内部实现机制,暂时无法了解孰优孰劣,不过,[NSThread isMainThread]貌似足矣!

volatile不简单

百科中,是这样描述它的:就像大家更熟悉的const一样,volatile是一个类型修饰符,它是被设计用来修饰被不同线程访问和修改的变量。作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值

简单说,被volatile修饰的变量是多线程安全的,其次,不会因为编译器优化导致读值出错。关于编译器编译优化可以看看这篇文章

iOS开发中确保多线程安全的方法有很多,原子操作、线程锁、单线程执行等等,本人也写过相关文章iOS开发多线程同步

在RN中,通过volatile修饰符,巧妙实现了多线程取消操作

__block volatile uint32_t cancelled = 0;

if (!cancelled) {

    // to do...

}

OSAtomicOr32Barrier(1, &cancelled);

通过原子性操作访问被volatile修饰的cancelled对象即可保障函数只执行一次。想想大家熟悉的单例dispatch_once_t,现在让你设计单例对象,你又会如何设计了?

+ (instancetype)sharedInstance {

    static RCTWebSocketManager *sharedInstance = nil;

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        sharedInstance = [self new];

    });

    return sharedInstance;

}

结构体Struct

说起Struct,不知各位对它印象如何?大学C课本中学过?NSObject类class原型貌似有讲?

struct iOSDev {

    NSString *nickName;

};

OC中一个简单的结构体,在Swift中,Struct也可以这样写

struct iOSDev {

    var nickName : String

    func getBusinessCard() -> String {

        return "\(nickName),幽默的iOS开发者!"

    }

};

let iOSOlinone = iOSDev(nickName: "olinone")

print(iOSOlinone.getBusinessCard())

getBusinessCard为结构体函数,是不是感觉很方便!其实OC中也可以这样写

struct iOSDev {

    NSString *nickName;

    NSString *getBusinessCard() {

        return [NSString stringWithFormat:@"%@,幽默的iOS开发者!", nickName];

    }

};

iOSDev iosDev = iOSDev{@"olinone"};

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

当然,为Struct添加函数并不是C语言特性,而是C++特性,因此,为了编译通过,你需要将.m文件修改成.mm文件

Struct有其使用的特殊场景,相较于Class,合理的使用Struct可以使代码更加整洁。同时,为了适应Swift中Struct强大特性,可以试着在OC项目中尝试Struct

最后,给大家来个段子吧:

话说一美女要在两个男人之间做选择,一个年纪大,长的丑,是个千万富翁,另一个年轻,帅气,iOS开发程序猿。 她对他们说,我会给你们一人一张纸条,写着我愿意的那张就是我的选择。 富翁打开纸条,看见上面写着我愿意,于是搂着她,坐上豪车高兴的走了。 年轻的小伙很伤心,打开纸条看见上面写着:“等我一个月~”  ^o^


写在文后:

有些童鞋可能经常会问一个问题,感觉自己技术遇到瓶颈,如何才能进一步提升自己技术能力?其实这个问题,本人也是摸石头过河,不过有一点可以确定,那就是保持一颗不断进取的心吧

新建了一个iOS开发QQ交流群(首页右上角入群),欢迎广大iOS开发朋友一同交流学习。当然,你也可以Follow本人GitHub,或者关注我的新浪微博,感谢你的来访,下期再见!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351

推荐阅读更多精彩内容

  • 史上最全的iOS面试题及答案 iOS面试小贴士———————————————回答好下面的足够了----------...
    Style_伟阅读 2,346评论 0 35
  • iOS面试小贴士 ———————————————回答好下面的足够了------------------------...
    不言不爱阅读 1,970评论 0 7
  • 多线程、特别是NSOperation 和 GCD 的内部原理。运行时机制的原理和运用场景。SDWebImage的原...
    LZM轮回阅读 2,004评论 0 12
  • ———————————————回答好下面的足够了---------------------------------...
    恒爱DE问候阅读 1,713评论 0 4
  • __block和__weak修饰符的区别其实是挺明显的:1.__block不管是ARC还是MRC模式下都可以使用,...
    LZM轮回阅读 3,297评论 0 6