iOS原生接入CRN步骤


一、安装ReactNative及code-push

1.安装rn项目依赖

新建文件夹foldername,在foldername下clone健客医院iOS项目及健客医院RN项目目录结构如下:

命令行进入RN项目根目录,执行npm install,安装node依赖模块。

2.安装iOS项目依赖

进入iOS项目文件夹,编辑Podfile文件,添加RN及code-push依赖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# RN相关
pod 'React', :path => '../DoctorBonusPoints/node_modules/react-native', :subspecs => [
'Core',
'CxxBridge',
'RCTImage',
'DevSupport',
'RCTText',
'RCTNetwork',
'RCTWebSocket',
'RCTActionSheet',
'RCTLinkingIOS',
'RCTAnimation'
]
pod 'CodePush', :path => '../DoctorBonusPoints/node_modules/react-native-code-push'
pod 'RNGestureHandler', :path => '../DoctorBonusPoints/node_modules/react-native-gesture-handler'
pod 'yoga', :path => '../DoctorBonusPoints/node_modules/react-native/ReactCommon/yoga'
pod 'DoubleConversion', :podspec => '../DoctorBonusPoints/node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
pod 'glog', :podspec => '../DoctorBonusPoints/node_modules/react-native/third-party-podspecs/glog.podspec'
pod 'Folly', :podspec => '../DoctorBonusPoints/node_modules/react-native/third-party-podspecs/Folly.podspec'

打开命令行,在iOS项目根目录下执行pod install,安装成功后。打开iOS项目,手动删除Pods target下的Development Pods文件夹内的React文件夹,也就是删除刚刚安装的RN的依赖库。去github下载CRN开源项目,下载成功后解压,文件结构如下:


将CRN文件夹和ReactNative文件夹拷贝到健客医院项目的JianKeDoctor目录下。打开健客医院iOS项目添加文件夹下子工程依赖如图所示:

点击xode 左上角项目target,选择 edit scheme如图所示,点击build选项卡,点击加号添加React编译依赖,取消勾选parallelize选项,注意要把React放在最上边使之先编译。

进入工程的buildphases添加library

点击build settings选项卡,找到Header Search Paths选项,添加搜索路径

1
2
${SRCROOT}/JianKeDoctor/RNLib/ReactNative
${SRCROOT}/JianKeDoctor/CRN

搜索路径都设置为recursive,递归查找。

到此安装工作结束。

more >>

GCDTimer

NSTimer

相关参数介绍

1.interval: 时间间隔,单位秒,如果设置小于0,系统默认是0.1
2.target: 定时器的绑定对象,一般是当前控制器self
3.selector: 需要执行的实例方法(减号方法)
4.userInfo: 传递相关信息
5.repeats: 是否循环
6.block: 需要执行的代码块,等同于 selector方法
7.invocation: 需要执行的方法
8.fireDate: 触发时间

创建方式
  • timerWithTimeInterval
  • scheduledTimerWithTimeInterval
  • initWithFireDate

常用的应该是前俩种,timerWithTimeIntervalinitWithFireDate需要手动加入到runloop中,而scheduledTimerWithTimeInterval会将定时器自定加入到当前的runloop,即NSDefaultRunLoopMode

问题

由于定时器会对使用对象(target)强引用,当界面对定时器强持有的时候,这时候会造成循环引用,比较常见的问题就是在即将要释放的ViewController不走它的dealloc方法,所以在dealloc方法中[self.timer invalidate]不会生效

more >>

dealloc用法

使用场景

MRC

1
2
3
4
5
6
7
8
9
- (void)dealloc {
self.array = nil;
self.string = nil;
// 移除观察者
// 移除通知
// 非Objc对象内存的释放,如CFRelease(...)
// ... //
[super dealloc];
}

ARC

1
2
3
4
5
6
- (void)dealloc {
// 移除观察者
// 移除通知
// 非Objc对象内存的释放,如CFRelease(...)
// ... //
}

对比发现:

1.对象的实例变量释放不见了
2.没有显示的调用[super dealloc],上层的析构不见了

more >>

深入探讨Block循环引用

循环引用由来

俩个对象相互强引用,俩个对象的retainCount一直无法为0,内存无法释放造成内存泄漏;
多个对象同理;

一. __strong __weak实现原理

所有权修饰:符:__strong,__weak,__unsafe_unretained,__autoreleasing;
所有权修饰符默认不写是__strong

__strong示例

对象持有自己
生成的时候用alloc/new/copy/mutableCopy

声明一个__strong对象

1
2
3
{
id __strong obj = [[NSObject alloc] init];
}

LLVM编译器转换为

1
id __attribute__((objc_ownership(strong))) obj = ((NSObject *(*)(id, SEL))(void *)objc_msgSend)((id)((NSObject *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("NSObject"), sel_registerName("alloc")), sel_registerName("init"));

简单的调用

1
2
3
id obj = objc_msgSend(NSObject, @selector(alloc));
objc_msgSend(obj,selector(init));
objc_release(obj);

由于在ARC下,会自动插入release代码,所以不难理解

more >>

盒子模型

好久没有更新博客了,前段时间家里有事,加上刚换了新公司,一直在忙于熟悉业务,没时间更新博客(主要是懒病犯了),新公司最近在忙于小程序推广,时间紧迫加上人员不足,因此也加入了小程序队伍,今天先学习下盒子模型

  • 元素设置为dispaly:flex display:inlin-flex称为伸缩容器;
  • 伸缩容器内的元素撑为伸缩项目;
  • 伸缩容器有俩根轴,默认横向主轴,纵向是交叉轴

伸缩容器的属性

  • display
    • 判断是否为伸缩容器: display:flex,display:inlin-flex
    • flex:块级
    • inline-flex:行内级
  • flex-deraction
    • 指定主轴方向
    • row 默认 横向
      • 横向 从左到右排
    • row-reverse
      • 横向 从右到左排
    • column 纵向
      • 纵向 从上到下排
    • column-reverse
      • 纵向 从下到上排
  • flex-wrap
    • 判断主轴方向空间不够,换行问题
    • nowrap 不换
    • wrap 九宫格排列换
    • wrap-reverse 跟wrap相反
  • flex-flow
    • flex-deractionflex-deraction缩写,连写俩个属性
    • flex-wrap:flex-deraction flex-deraction
  • justify-content
    • 伸缩项目沿着主轴的对齐方式
    • flex-start 默认值 向起始位置靠齐
    • flex-end 向结束位置靠齐
    • center 向中间靠齐
    • space-between 平均分布,第一个在初始,最后一个在末端
    • space-around 平均分布,俩端留一半空间
  • algin-items
    • 伸缩项目在交叉轴(垂直于主轴)上的对齐方式
    • flex-start 默认值 向起始位置靠齐
    • flex-end 向结束位置靠齐
    • center 向中间靠齐
    • baseline 基线对齐 类似垂直y对齐
    • stretch 在交叉轴拉伸充满整个伸缩容器
  • align-content
    • 调整伸缩项目出现换行后在交叉轴上的对齐方式,类似伸缩项目在主轴上使用justify-content

more >>

iOS核心动画技巧学习-CALayer常用属性2

阴影

阴影作为一个iOS的常见特性,可以达到图层深度暗示的效果,更多的目的是单纯的装饰(┑( ̄Д  ̄)┍)

  • shadowOpacity—- 默认值是0,范围是(0-1),改变这个值,阴影就可以显示在任意图层之下 ,若想自定义,请往下看
    • shadowColor – 默认是黑色, CGColorRef 类型
    • shadowOffset – 默认{0,-3}, CGSize 类型;第一个参数控制阴影横向位移,第二个参数控制纵向位移,默认是阴影相对于Y轴有3个点的向上偏移;此处默认向上偏移是因为虽然 Core Animation 是为iOS创建的私有动画框架,但是却是先在 Mac OS上面世的,而且iOS和Mac OS的Y轴是颠倒的.在Mac上, shadowOffset 默认值是阴影偏下的

      more >>

iOS核心动画技巧学习 - CALayer处理事件

CALayer 并不关心任何的响应链事件,所以也不能直接处理触摸事件或者手势;但是它有俩个方法帮你处理事件 -containsPointhitTest

-containtPoint
  • 接收一个本图层坐标系下的 CGPoint,如果这个点在图层的 frame 范围内返回 YES

    more >>

iOS核心动画技巧学习 -- 布局

  • UIView: frame bounds center
  • CALayer: frame bounds position

    • frame : 代表了图层外部坐标(在父视图上占据的空间)
    • bounds: 是内部坐标({0,0},通常是当前图层的左上角)
    • center 视图的中心点
    • position 代表当前图层相对于图层的锚点(anchorPoint)所在父层中的位置
    • frame 属性是依据 bounds position transform 计算而得的,其中的一个值发生改变, frame 也会改变,反之亦然
    • 当对图层做变换(旋转或缩放)的时候, frame实际上代表了覆盖在图层旋转之后的整个轴对齐的矩形区域,此时 frame 的宽高和 bounds 的宽高不一样

      more >>

iOS核心动画技巧学习 -- drawRect方法

  1. -drawRect 简介
    1. 除了使用给 contentsCGImage来添加图片,我们也可以使用 Core Graphics 直接绘制.能通过继承 UIView 来实现 -drawRect 实现自定义绘制
    2. -drawRect 默认是没有实现的,因为对 UIView 来说,这个图层的图片不是必须的,它并不在意图层上到底是单调的颜色还是一个图片的实例;如果 UIView 检测到了 -drawRect 方法被调用了,它就会给视图分配一个图层里的图片,这个图层里图片的像素尺寸等于视图大小乘以 contentsScale 的值
    3. 但是如果不需要图层里面的图片,就不要啊创建,因为会造成CPU资源和内存的浪费(苹果也是这样建议的,如果没有自定义的任务就不要在子类中写一个空的 -drawRect 方法)

      more >>

iOS核心动画技巧学习 -- CALayer常用属性

  • contents属性
    • 类型
      • id类型的历史原因:因为在MAC OS系统上,这个属性对CGImageNSImage的类型值都起作用
      • 但是在iOS平台将UIImage赋值给它,编译会通过,然后你得到的图层将是空白的
      • 但是其实我们真正要赋值的类型应该是CGImageRef,是一个指向CGImage结构的指针;不过UIImage有一个CGimage属性,它返回一个CGImageRef,点击进去UIImage的头文件可以看到:@property(nullable, nonatomic,readonly) CGImageRef CGImage; // returns underlying CGImageRef or nil if CIImage based

        more >>

这个人很帅<br>他什么都不想说<br>