由于本人能力有限,难免有错,欢迎批评、指正、补充,目录请看右下角
Foundation复习
- 利用category + runtime + 异常的捕获 来写一个防止崩溃的框架
- 扩展(Extension)处理containing app与扩展之间的通信、共享数据等
- App之间的数据共享——App Group的配置
- NSHashTable & NSMapTable
- 详解iOS App开发中Cookie的管理方法
- 在iOS App 中进行自然语言处理:初探NSLinguisticTagger
- 本地化
- NSNetService和NSNetServiceBrowser(Bonjour网络编程)
- Hello Bonjour!
- NSNotificationQueue异步通知
NSNotificationQueue异步通知
两个一起看吧 异步通知+重定向 - 可变/不可变类簇的缺点。这篇文章牛逼可拉斯
- 描述任务进度: NSProgress
- 使用 NSPropertyListSerialization 持久化字典与数组
- 用 NSProxy 实现面向切面编程
- 正则表达式NSRegularExpression类详解
- NSScanner使用详解
- iOS:NSScanner,一个陌生的条件判断利器!
- 浅析排序规则描述类: NSSortDescriptor
- iOS中字符串的基本用法,不是很全还可以
- iOS中正则表达种类
- NSTimer的使用
- 开发中的日期--NSDate & NSTimeZone
- iCloud Storage 详细的官方文档
- NSUndoManager
- 使用 NSUndoManager 来进行撤销和重做
- NSURL
- 详细解析几个和网络请求有关的类
- NSURLProtectionSpace
- iOS下的黑魔法NSURLProtocol
- 黑魔法NSURLProtocol 简单明了
- iOS模拟网络之OHHTTPStubs库的介绍与使用
- iOS9 App Search之NSUserActivity与Core Spotlight
- Handoff:沟通iOS应用和网页
- NSUserDefaults详解
- 获取iOS设备唯一标示
- iOS开发技巧(系列十二:UUID和UDID的区别)
- 数据转换NSValueTransformer
- XPC 是 OS X 下的一种 IPC (进程间通信) 技术
UIKit复习
- NSDataAsset
- iOS9.0 NSLayoutAnchor初探
- NSTextStorage,NSLayoutManager,NSTextContainer和UITextView
- iOS弹出页神器Presentation Controllers 弹窗效果
- UISplitViewController Master / Detail
- iOS 应用状态恢复 UIStateRestoration
- 如何实现UITabbarController 的State Restoration?
- UIStepper - 步进控件
- 使用苹果原生的UIVideoEditController进行视频编辑
其他知识点回顾
RunLoop、RunTime、多线程、锁
- iPhone X 设计尺寸和适配
- iPad和iPhone开发的异同
- iOS动态性(一) 一行代码实现iOS序列化与反序列化(runtime)
- iOS黑魔法-Method Swizzling 方法交换+利用category + runtime + 异常的捕获
- Method Swizzling 特殊情况也考虑了很好
- RunLoop入门
- RunLoop 应用
- 深入理解RunLoop
- Mach消息发送机制
- 进程间通信 (OSX/iOS)
- iOS刨根问底-深入理解RunLoop
- 《深入解析Mac OS X & iOS操作系统》读书笔记 内核相关知识
- property(class)
- iOS多线程实现方案之 -- NSThread
- iOS-图文表并茂,手把手教你GCD,同步异步+串行并行讲解 非常好
- GCD功能讲的很全面
- 使用信号量(dispatch_semaphor)实现GCD下的并发和同步
- NSOperation, 写的很到位
各种锁
Data race的定义很简单:当至少有两个线程同时访问同一个变量,而且至少其中有一个是写操作时,就发生了Data race。
原子操作: 表示一条不可打断的操作,也就是说线程在执行操作过程中,不会被操作系统挂起,而是一定会执行完。
临界区:指的是一块对公共资源进行访问的代码,并非一种机制或是算法
你调用 sychronized 的每个对象,Objective-C runtime 都会为其分配一个递归锁并存储在哈希表中
复制代码
- iOS开发中的11种锁以及性能对比
- 深入理解 iOS 开发中的锁
- 使用信号量(dispatch_semaphor)实现GCD下的并发和同步
- 关于 @synchronized,这儿比你想知道的还要多
- 不再安全的 OSSpinLock
- NSRecursiveLock递归锁的使用
- iOS多线程到底不安全在哪里?
- 如何用Xcode8解决多线程问题
网络相关
- HTTP in iOS你看我就够******
- 请求类NSURLRequest和请求响应类NSURLResponse介绍
- NSURLSession、NSURLSessionConfiguration 算不错的了
- 从 NSURLConnection 到 NSURLSession、 NSURLSessionConfiguration
- NSURLSessionConfiguration
- NSURLSessionConfiguration
- 深入了解NSURLSession 这篇文章不错
- Google Protocol Buffer 的使用和原理 Protobuf
- AFNetworking3.1.0源码分析 整体框架和功能模块
- iOS AFNetWorking源码详解
- AFNetworking源码阅读系列
- AFNetworking到底做了什么?
- iOS网络——身份认证
- iOS开发HTTPS实现之信任SSL证书和自签名证书
- iOS - HTTPS
- NSURLAuthenticationChallenge官方文档阅读
- "数字签名"(digital signature)和"数字证书"
- iOS App 签名的原理
- 数字证书的原理是什么
- HTTPS 原理与实现
- iOS HTTPS适配
- 1、 99%的人都理解错了HTTP中GET与POST的区别
- 2、 翻转上面文章 HTTP协议中GET和POST方法的区别
- SSL/TLS协议运行机制的概述
计算机网络
- 集线器和交换机的区别?
- 上网限制和基本原理
- 十分钟学会Charles抓包(iOS的http/https请求)
- 抓包工具Charles的使用教程
- [这块自己看上学时候的计算机网络的书,我自己是手写笔记的]
组件化
- 组件化架构漫谈 中间件方案,非常好
- 依赖注入
- Mock
- 控制反转与依赖注入模式
架构思想 设计模式
- 组合模式
- 跳出面向对象思想(一) 继承
- 跳出面向对象思想(二) 多态 面向接口编程 iop
- casatwy 的博客
- 组合模式(Composite Pattern)
- iOS 设计模式-结构模式-组合模式
- 代理丶通知丶KVO之间区别和各自优势
- 代理和通知的异同
- iOS中的链式编程
- 深入浅出-iOS函数式编程的实现 && 响应式编程概念
生命周期
- iOS程序执行顺序和UIViewController 的生命周期(整理)
- iOS 程序启动流程解密,main函数执行之前流程
- iOS APP启动流程,主要是main函数执行流程
- dyld 加载 Mach-O
- 趣探 Mach-O:加载过程
- 你真的了解 load 方法么?
- NSObject的load和initialize方法
- iOS - + initialize 与 +load
- 通过StoryBoard加载控制器&通过Xib加载控制器
- awakeFromNib的调用机制
- layoutSubviews总结(作用及调用机制)
- 多控制器切换生命周期
- viewDidLayoutSubviews 与 layoutSubviews 调用顺序
适配相关
- iOS 8 AutoLayout与Size Class自悟
- iOS8 Size Classes的理解与使用
- iOS自动布局框架-Masonry详解
- iPhone X 设计尺寸和适配
- iOS 11 safeArea详解 & iphoneX 适配 safeAreaLayoutGuide、safeAreaInsets
- iOS开发-LayoutGuide(从top/bottom LayoutGuide到Safe Area)
- [UILayoutGuide]
- @available(iOS 11.0, *) iOS11新增版本判断API
- 适配iOS11&iPhoneX的一些坑
- Masonry是如何适配iOS11的
- automaticallyAdjustsScrollViewInsets解析
- iOS 多版本适配
动画相关 QuartzCore&CoreGraphics
----QuartzCore-----
- anchorPoint
- 彻底弄清 anchorPoint 和 position
- CALayer api详解
- CALayer的contents属性
- 专用图层,CALayer的子类
- iOS动画原理--隐式动画
- 事物CATransaction
- 通过CATransaction关闭隐士动画
- CAAnimation wiki 缺转场和动画组
- CATransition—转场动画
- CAAnimationGroup—动画组
- CADisplayLink
- [CAAction&CAMediaTiming]
- [layer树形结构]
- iOS动画-从UIView动画说起
- 核心动画与UIView动画的区别
- 动画解释
- Core Animation Programming Guide 官方文档
- iOS Core Animation: Advanced Techniques中文译本
----CoreGraphics----- - CGContextRef类详解
- iOS Quartz 2D绘图知识详解, 有质量
- Core Graphics简介
--UIDynamic---
- iOS中UIDynamic物理仿真详解
事件传递相关
- 理解UITouch,UIEvent,UIGestureRecognizer以及UIResponder
- 手势的3个容易混淆的属性 cancelsTouchesInView/delaysTouchesBegan/delaysTouchesEnded
- UITouch
- UIEvent
- 响应者链条
- [CALayer中也有hitTest:方法]
- CALayer处理点击事件
- CALayer响应点击事件 Swift
- iOS-手势UIGestureRecognier详解
- iOS开发系列--触摸事件、手势识别、摇晃事件、耳机线控
- [离散手势+连续手势]
- [多手势冲突]
- [自定义手势]
本地+远程推送
- iOS 10 消息推送(UserNotifications)秘籍总结(一)
- iOS 10 消息推送(UserNotifications)秘籍总结(二)
- iOS远程推送原理及详细实现过程(前端后台)
- iOS10里的通知与推送
- [通知跳转至相应连接,页面]
- [第三方远程推送]
- [UserNotifications.framework]
- 玩转 iOS 10 推送 —— UserNotifications Framework(上)
Swift与OC、C++与OC混合开发、js交互、 Hyrb相关、MRC与ARC混编
- 在OC项目中实现swift与oc混编 相互引用
- 混编ObjectiveC++
- Using C++ With Objective-C
- iOS 引用 C/C++ 项目:交叉编译与 Objective-C++
WebKit.framework
- iOS (一) - UIWebView 与 WKWebView . 基本使用
- WKWebView详解 (https://upload-images.jianshu.io/upload_images/10203750-48c74dd4543140ca.png)
- WKWebView NSHipster
- WKWebView详解
- iOS与H5的交互【WKWebView】
NSHTTPCookieStorage
- iOS中Cookie介绍
- iOS HTTP网络请求Cookie的读取与写入(NSHTTPCookieStorage)
- WK、UIWebview、AFN添加cookie
- cookie 版本
- cookie 原理
- Cookie
JavaScriptCore.framework
- JavaScriptCore 使用
- 深入浅出 JavaScriptCore
- JavaScriptCore全面解析 (上篇)
- JavaScriptCore全面解析 (下篇)
- [JSExoprt协议底层实现]
- [JSValue、JSContext内存管理]
Foundation与CoreFoundation桥接
- iOS中Foundation与Core Foundation的桥接
- CoreFoundation框架详细解析(十一) —— 自由桥接类型
- 桥接
预编译指令
- C语言预处理命令详解
- typedef和#define的用法与区别
#define 没有参加编译,在预处理的时候就被替换掉了。
typedef参加编译和链接。
typedef是重命名,可以为枚举结构体等等重新命名,提高代码整洁。
复制代码
- const/static/extern/typedef/typeof/define的释义和用法
- iOS预编译指令详解
- iOS预编译指令
- 宏定义的黑魔法 - 宏菜鸟起飞手册 oneCat
正则 Regular Expression
- iOS正则表达式
- iOS常用正则表达式
- iOS正则表达式(NSRegularExpression)
- iOS开发-正则表达式的使用方法
NSPredicate
- iOS中的谓词(NSPredicate)使用
NSRegularExpression
- oc中正则表达式NSRegularExpression类详解
持久化相关
- iOS应用架构谈 本地持久化方案及动态部署
property list
- Info.plist字段列表详解
- iOS动态性(一) 一行代码实现iOS序列化与反序列化(runtime)
沙盒
- 沙盒官方文档
- 沙盒和NSBundle
沙盒是三个Container可不只是Document、Library\Cache|Preferences、Temp这三个
---MyApp---
-- 1. BundleContainer(MyApp.app)
-- 2.DataContainer(Document、Library\Cache|Preferences、Temp、SystemData这个新发现的)
--3. iCloudContainer
复制代码
-[在组件化开发中要注意bundle的获取]
SQLite/FMDB
FMDatabaseQueue 解决这个问题的思路是:创建一个队列(串行线程队列),然后将放入的队列的block顺序执行,这样避免了多线程同时访问数据库
复制代码
- SQLite 简单教程
- libsqlite3.0.tbd和libsqlite3.tbd
- Sqlite3数据库的基本使用
- DML——SQLite数据库
- FMDB的线程安全
- 在iOS开发中使用FMDB 唐巧
- [通过item动态创建表]
keyChain
- 谈谈iOS Keychain的使用
- iOS 开发 之 keychain详解及变化
- iOS Keychain使用说明
- 多个APP之间共享keychain数据的使用
- Apple的开发着文档上有Keychain的完整使用实例
- iOS 10.3 keychain功能重大更改
- [Security.framework/SecItem.h]
- [第三方SAMKeychain]
CoreData
- [暂时不整了]
NSUserDefaults
- iOS数据存储 NSUserDefaults的使用
- iOS/NSUserDefaults详解
- NSUserDefaults registerDefaults
- NSUserDefaults详解
- [NSUserDefaults存储位置 /Library/Prefereces,里面有个plist文件]
- [域]
App Groups
- App之间的数据共享——AppGroup的配置
优化工具
Instruments
- Launch Instruments几种方法
- Xcode 8 Instruments 学习(一)
- Time Profiler 的使用
Allocations对app优化非常有用,通常是拿来分析内存增加(不一定是内存泄漏)和app中各部分占用内存问题,当我们得知哪个内存占用比较多,我们直接进行优化即可减少内存占用问题
Generation Analysis
这个功能是非常有用的,一般是这样用的:进入一个页面前mark一下,在退出这个页面的时候再mark一下可以比较哪些内容增加了,就可以具体分析哪些内存没有被释放;比如我们要进入日程界面的时候我点了一下mark
复制代码
- Instruments的 Allocations使用
- instruments之Allocations
- Instrument之Allocations
- [UIAutomation]
静态分析Analyze、 监控僵尸对象、 memory graph 、 Debug View Hierachy
Crash搜集相关
- iOS开发之Crash日志获取与分析
- iOS Crash文件的解析(一)
- 浅谈iOS Crash(一)
- 浅谈iOS Crash(二)
- 漫谈iOS Crash收集框架
Mach异常 、Unix Signal 和 NSException
1. Mach异常是最底层的内核级异常,如EXC_BAD_ACCESS(内存访问异常)
2. Unix Signal是Unix系统中的一种异步通知机制,Mach异常在host层被ux_exception
转换为相应的Unix Signal,并通过threadsignal将信号投递到出错的线程。如SIGABRT(
程序中止命令中止信号)、SIGALRM(程序超时信号),具体信号枚举在iOS的sys/signal.
h文件中。 它们可以利用Unix标准的signal机制来处理。
3. 当错误发生时候,先在最底层产生Mach异常;Mach异常在host层被转换为相应的Unix
Signal; 在OC层如果有对应的NSException(OC异常),就转换成OC异常,OC异常可以在
OC层得到处理;如果OC异常一直得不到处理,程序会强行发送SIGABRT信号中断程序。在
OC层如果没有对应的NSException,就只能让Unix标准的signal机制来处理了。
复制代码
僵尸对象:已经被释放掉的对象。一般来说,访问已经释放的对象或向它发消息会引起
错误。因为指针指向的内存块认为你无权访问或它无法执行该消息,这时候内核会抛出
一个异常( EXC ),表明你不能访问该存储区域(BADACCESS)。(EXC_BAD_ACCESS类型错误)
野指针是指向一个已删除的对象或未申请访问受限内存区域的指针。而这里的野指针主
要是对象释放后,指针未置空导致的野指针。该类Crash发生比较随机,找出来比较费劲
,比较常见的做法是,在开发阶段,提高这类Crash的复现率,尽可能得将其发现并解决。
向OC对象发出release消息,只是标记对象占用的那块内存可以被释放,系统并没有立即
收回内存;如果此时还向该对象发送其他消息,可能会发生Crash,也可能没有问题。下
图是 访问野指针(指向已删除对象的指针)可能发生的情况。
复制代码
- [第三方平台搜集crash信息 PLCrashReporter、友盟、Bugly]
- [MLeaksFinder]
- [Crash 堆栈]
加密
- [对称非对称、md5信息-摘要算法、SHA散列、base64]
- iOS App 签名的原理
- 白话解释 对称加密算法 VS 非对称加密算法
- 数字签名是什么?
- 常用加密算法概述
- 各种加密算法比较
base64
- Base64 维基百科
对称加密
- [DES]
- [AES]
非对称加密
- RSA算法原理(一)
- RSA算法原理(二)
哈希算法HASH(散列算法)
- 什么是哈希表和哈希算法?
- Hash算法总结
- [HashMap与HashTable]
----hash流行算法-----
Hash函数的安全设计的理论主要有以下两点:一是函数的单向性,二是函数影射的随机性
hash算法是将输入内容变换为长度固定的输出,它主要是用于可以更快速地判断两个内容是否相同。
信息摘要是hash算法的一种,但拥有额外更严格的条件,例如不能逆运算,更严格的碰撞要求等。
复制代码
- MD5 128 Message-Digest Algorithm 5(信息-摘要算法)
- SHA家族算法 160
- [强抗碰撞性]
- [盐]
Jenkins+Docker、fastlane、fir.im/蒲公英 自动打包、单元测试、自动化测试、Xcode编译
持续化集成工具——Jenkins
iOS自动化打包命令——xcodebuild + xcrun 和 fastlane - gym 命令
打包完成自动化上传 fir / 蒲公英 第三方平台
CI 提供的是持续集成服务(Continuous Integration,简称 CI)。它绑定 Github 上面的项目,只要有新的代码,就会自动抓取。然后,提供一个运行环境,执行测试,完成构建,还能部署到服务器。
持续集成指的是只要代码有变更,就自动运行构建和测试,反馈运行结果。确保符合预期以后,再将新代码"集成"到主干。
持续集成的好处在于,每次代码的小幅变更,就能看到运行结果,从而不断累积小的变更,而不是在开发周期结束时,一下子合并一大块代码。
复制代码
---说真的我有点蒙蔽,没有真正实践过,只能以后参加新工作有机会弄了----
- Mac 配置Java环境
- jenkins+xcode+蒲公英实现ipa自动化打包
- 手把手教你利用Jenkins持续集成iOS项目
- iOS中使用Fastlane实现自动化打包和发布
- 小团队的自动化发布-Fastlane带来的全自动化发布
- 使用 fastlane 实现自动化打包
- [xcodebuild + xcrun命令]
- Jenkins+Docker搭建持续集成测试环境
- iOS 应用签名证书的类型说明
- iOS 设备的 UDID
- 向安装包中添加设备 UDID
- fastlane 一个快速将 iOS 项目打包成 ipa 文件的工具
- /bin /sbin/ /usr/bin/ /usr/loca/bin/ 各目录的区别
---单元测试----
- LZAlbum 里面有单元测试讲解
- XCTest各种断言
- 浅谈iOS单元测试XCTest
- iOS UnitTest单元测试覆盖率(Code Coverage)
- [线上测试环境 防止脏数据污染]
- [测试框架]
- [GitHub/GitLab提交pr时 jenkins自动跑测试]
- [slack]
- 持续集成服务 Travis CI 教程
app Thinning、封装动态库.dylib、封装静态库.a、封装带第三方的.a &.framework的sdk、封装.bundle
- iOS 应用打包 设备兼容性问题(Build Active Architecture Only)
---App Thinning相关---
- App Thinning
- 初探 iOS 9 的 App 瘦身功能
- On-Demand Resources Guide中文版(按需加载资源--上)
- On-Demand Resources Guide中文版(按需加载资源--下)
---封装动态库.dylib---
静态库: 一堆目标文件(.o/.obj)的打包体(并非二进制文件)
动态库: 一个没有main函数的可执行文件
静态库 常见的是 .a
动态库常见的是 .dll(windows),.dylib .tbd (mac),so(linux)
framework(in Apple): Framework 是Cocoa/Cocoa Touch程序中使用的一种资源打包方式,可以将代码文件、头文件、资源文件、说明文档等集中在一起,方便开发者使用
。也就是说我们的 framework其实是资源打包的方式,和静态库动态库的本质是没有关系的
Framework 可以选择创建为动态或者静态
静态库即静态链接库(Windows 下的 .lib,Linux 和 Mac 下的 .a)。之所以叫做静态,是因为静态库在编译的时候会被直接拷贝一份,复制到目标程序里,这段代码在目标程序里就不会再改变了。
静态库的好处很明显,编译完成之后,库文件实际上就没有作用了。目标程序没有外部依赖,直接就可以运行。当然其缺点也很明显,就是会使用目标程序的体积增大。
动态库动态库即动态链接库(Windows 下的 .dll,Linux 下的 .so,Mac 下的 .dylib)。与静态库相反,动态库在编译时并不会被拷贝到目标程序中,目标程序中只会存储指向动态库的引用。等到程序运行时,动态库才会被真正加载进来。
动态库的优点是,不需要拷贝到目标程序中,不会影响目标程序的体积,而且同一份库可以被多个程序使用(因为这个原因,动态库也被称作共享库)。同时,编译时才载入的特性,也可以让我们随时对库进行替换,而不需要重新编译代码。
动态库带来的问题主要是,动态载入会带来一部分性能损失,使用动态库也会使得程序依赖于外部环境。如果环境缺少动态库或者库的版本不正确,就会导致程序无法运行(Linux 下喜闻乐见的 lib not found 错误)。
这里的所谓静态和动态是相对编译期和运行期的:静态库在程序编译时会被链接到目标代码中,程序运行时将不再需要改静态库;而动态库在程序编译时并不会被链接到目标代码中,只是在程序运行时才被载入,因为在程序运行期间还需要动态库的存在。
复制代码
- 使用XCode7打包动态库/静态库
- 开发封装动态库framework
- 上面两个结合着看
_CodeSignature: 保存签名相关文件
Headers: framework暴露的所有头文件
Info.plist: 描述了该framework所包含的项目配置信息
STDemo: 编译后的核心库文件
Modules: 模块相关文件夹, 目测只包含了module.modulemap文件
复制代码
- iOS 上架动态被拒库问题
被苹果签名的动态库可以(会)iOS应用加载
一个简单的iOS应用在启动时会加载超过150个动态库
Xcode不支持创建iOS上的动态库,frameworks或者插件,但解决这些还是非常容易的事情
如果没有代码签名,我们将可以像在MacOS上在iOS上加载动态库,frameworks和在运行时加载插件
在实践中内核将会杀掉哪些尝试加载一个未签名或者签名不能被审核的动态库
***一个要上架的动态库同样需要被同一个用来上架AppStore应用的证书签名***
最后AppStore的政策绝不运行动态库,即使技术是做到了,它也通不过AppStore的审核。
复制代码
---封装静态库.a----
- ios打包静态库,看这篇就够了
- iOS - 从头开始封装 .a静态库
- iOS中的静态库与动态库,区别、制作和使用
- iOS封装库生成 .framework文件
- 两个结合看
----制作附带第三方.a或framework封装自己的SDK----
- xcode制作iOS静态库SDK<包含第三方.a或者.framework静态库>
** 如果将第三方SDK的framework包含在自己的静态库中,
一种方法就是打包的时候不打包进自己的静态库中,然后在调用静态库的时候再在程序中引入第三方的SDK即可**
iOS静态库SDK制作也有提到具体如何操作,.framewrok的库确实无法整体直接打包进静态库中。没有办法直接整体打包,那么法间接的引入
复制代码
在自己的framework中使用到了AFN,fmdb 等第三方库。如果我在add进自己framework的时候 不勾选 target,那么在使用我的framework的时候,项目里面就必须有这些三方库,不然就回报错。
如果我勾选了 target,那么我的项目中就不能有这些第三方库,不然也会报错 提示 duplicate symbol。
综上, 能不能让自己framework中的第三方库代码 和 项目中的第三方库代码完全独立呢?我问了一些朋友 说的是 修改自己sdk中的第三方库类名,还有相关的宏等。这样做工作了好大,还有更简单的方式吗?
木有更简单的方式了,一般来说 相对统一才是正道吧,我觉得放在项目里最合适,framwork的体积也可以减小,还可以保证项目中代码没问题,
就是如果更新第三方以后,你的framwork代码需要做更改,但是你不觉得 这个工作量更小点么
复制代码
----封装.bundle---
- iOS 把资源打包成bundle
- iOS-制作并调用Bundle资源包
---其他相关---
- [组件化frameworks]
- mach-o
- dyld
- [iOS 程序 main 函数之前发生了什么]
- iOS 设备的CPU架构
Architectures (架构)
指明选定的Target要求被编译生成的二进制包所支持的指令集,
而支持的指令集越多,就会编译出包含多个指令集代码的数据包,对应生成二进制包就越大,也就是ipa包会变大。
复制代码
调试技巧、编码规则、数据采集与埋点、发布流程
---调试技巧----
- LLVM与Clang的概述及关系
- LLVM + Clang
lldb 是llvm的调试器
复制代码
- iOS开发调试 - LLDB使用概览
- iOS各种调试技巧豪华套餐
- iOS Xcode调试技巧总结
- 与调试器共舞 - LLDB 的华尔兹
- [Xocde 堆栈信息 这里在Crash那里记录]
- Build 过程
- iOS学习之深入理解程序编译过程
- iOS编译过程的原理和应用
---数据采集与埋点---- - 手把手教你进行APP数据埋点
- iOS埋点
- 可复用且高度解耦的iOS用户统计实现
- 1. iOS无埋点数据SDK实践之路 超赞?
- 2. iOS无埋点数据SDK的整体设计与技术实现
hook的方法大致可以分为3类:系统类的方法、系统类的Delegate方法、自定义类的方法。
viewPath 及 viewId 的生成及优化
1. SDK 在生成 viewPath 时,只到 view 所在的 UIViewController 级别,而非根部的 UIWindow。这样做也在一定程度上减少了viewPath 的长度。
2. viewPath只表示到距离 view 最近的一个 VC
3. UITableViewCell/UICollectionCell 的深度表示:虽然每个 Cell 都可能被复用,但是不同的 Cell 都对应一个唯一的indexPath,因此完全可以使用indexPath值来表示其深度
4. SDK 为了在新增/移除某一 view 时,尽量减少对已有 view 的深度的影响,调整了对节点的深度的计算方式:采用当前 view 位于其父 view 中的所有 同类型 子 view 中的index 值。
它的可读性很差。因此在此基础上又增加了每个节点的名称,节点的名称由当前节点的 view 的类名来表示。
5. 在包含子VC时,优化VC的深度的计算
5.1 由于子VC的展现顺序可能不同,这种情况导致 viewPath 不可靠且无法保证唯一性
5.2 VC 的深度的计算:不再采用其 view 的深度,而是直接使用固定的0。因为 VC 已经是viewPath的根级别了,它的深度信息已经不重要了。
5.3 如果上述子 VC 的 VC1 和 VC2 是同一个类的不同实例,那么他们内部的视图结构是完全一样的,这时候如果使用固定的 VC 深度(0),通过viewPath就无法区分具体是哪个子 VC 的 view 了。
针对这种同一类的不同实例,如果想进一步区分它们,SDK 采用了另一个方案:****页面别名****。????
viewPath:HYGHallSlideViewController-UIScrollView-HYGHallProductTableView-UITableViewWrapperView-HYGHallProductCell-UITableViewCellContentView-HYGHallProductView & 0-0-1-0-0:2-0-1
路径中各个节点的深度是:0-0-1-0-0:2-0-1
HYGHallSlideViewController[0]/UIScrollView[0]/HYGHallProductTableView[1]/UITableViewWrapperView[0]/HYGHallProductCell[0:2]/UITableViewCellContentView[0]/HYGHallProductView[1]
0:2表示cell的第0组第二行。indexpath的写法
**圈选:您需要根据业务需求,将需要分析的关键元素告诉我们。这个过程,就是圈选**
6. viewId:为了便于后台使用它作为 view 的唯一标识。因此 SDK 使用viewPath信息通过MD5加密生成一个固定长度的值作为viewId
7. iewPath 与 viewId 重复时的解决方案
7.1 有时同一个viewPath的 view 具有不同的表现形式与作用,同一个viewPath对应多个事件,此时如果只使用viewPath无法区分出不同的状态或事件。
7.2 DK 的解决方案是:viewPath + “其它信息” 。这里的 “其它信息” 是视不同情况而定的,比如: 在上面的情况1中,“其它信息” 就是按钮的 title
SDK 在进行数据收集时,会上传 view 的这些信息,再结合圈选SDK就能让后台在做统计时区分出这些不同的事件了。
8. 基于 viewPath 与 KVC 实现 SDK 的无埋点业务数据收集功能的实现
实现 SDK 的无埋点数据收集时,主要分为3步:上传KVC配置、请求KVC配置、业务数据的收集与上报。
8.1 KVC配置 就是一些用来描述 App 应该在什么时机去收集什么数据的信息,包含的主要信息有:
appKey:用来标识是哪个应用
appVersion:用来标识应用的版本号
viewEvent:标识某个事件类型(收集时机),例如:ButtonClick、ListItemClick、ViewTap等
viewPath:目标 view 在viewTree中的信息
keyPath:目标 view 与要收集的业务数据间的关联路径,用于KVC取值
keyName:为要收集的业务数据定义一个key,最终组成 key-value 的形式上报。用于区分多个收集的数据
8.2.1 上传KVC配置
利用 圈选SDK 上传 KVC配置 的操作对于用户是透明的,主要由开发人员进行上传与管理。
此操作可以在任何时候进行,在想要收集某个或某些版本的 App 中的业务数据时,上传相应的KVC配置信息至后台即可,达到了根据需要动态可配的效果。
8.2.2 请求KVC配置
SDK 在初始化时会触发 KVC配置 的请求操作,从后台拉取 App 当前版本对应的所有KVC配置,并将请求结果缓存起来,以提供给下一步使用。
8.3 业务数据的收集与上报
这个环节的核心是基于viewPath的 view 匹配,
主要实现是通过循环遍历viewPath的每个节点的信息与当前 view 及其父view 依次进行匹配。
因此这一步会产生一定的时间与性能消耗。为了尽可能减少这部分的操作,SDK 中使用了一些方式进行优化,其中一个就是基于缓存view的优化。
8.4 具体匹配原则和优化看上面文章
复制代码
- 美团点评前端无痕埋点实践
- “无埋点” GrowingIO 超赞?
- “无痕埋点" mixpanel-iphone
第一类是代码埋点,即在需要埋点的节点调用接口直接上传埋点数据,友盟、百度统计等第三方数据统计服务商大都采用这种方案;
第二类是可视化埋点,即通过可视化工具配置采集节点,在前端自动解析配置并上报埋点数据,从而实现所谓的“无痕埋点”, 代表方案是已经开源的Mixpanel;
第三类是“无埋点”,它并不是真正的不需要埋点,而是前端自动采集全部事件并上报埋点数据,在后端数据计算时过滤出有用数据,代表方案是国内的GrowingIO。
复制代码
- [友盟埋点]
- [减少埋点入侵 aop]
- [避免每次点击都触发埋点,可以缓存一些在触发埋点请求]
----上架流程----
- 2018最详细iOS APP上架App Store流程
- App上架流程(2017)
- App上架流程(2016详细版)
- iOS 应用签名证书的类型说明
- 打包 iOS 的 IPA 文件
- [.p12]
内存相关
- 内存五大分区
- C特性之 内存五大区域
- iOS内存管理(MRC、ARC)深入浅出
- weak 实现原理
- iOS 底层解析weak的实现原理(包含weak对象的初始化,引用,释放的分析)
- OC-底层实现isa指针
- 从 NSObject 的初始化了解 isa
- 浅谈iOS Crash
- 野指针和僵尸对象
- Autorelease自动释放池底层实现
- 深拷贝与浅拷贝
- [内存泄漏场景]
- [监测僵尸对象]
- iOS内存泄漏自动检测盘点 Instrument — Leaks,Instrument — Allocations,Analyze, Debug Memory Graph、第三方
- Xcode Analyze静态分析
- @weakify, @strongify
- MLeaksFinder:精准 iOS 内存泄露检测工具
- MLeaksFinder 新特性
- MRC与ARC混编
- [Instrument — Leaks,Instrument — Allocations,Analyze, Debug Memory Graph、第三方]
常见控件使用和优化
- UIResponder 和 UIControl
- UIControl 的基本使用方法和 Target-Action 机制
- iOS11及Xcode9适配问题汇总
1. UIScrollView
- UIScrollView的用法
- iOS 11 UIScrollView的变化
2. UITableView :UIScrollView、UITableViewCell、UITableViewController、UITableViewHeaderFooterView
- UITableView详解 (持续更新)
- UITableView API详解
- UITableViewCell API详解
- @protocol UITableViewDataSourcePrefetching iOS10 预加载特性
- UITableViewCell中的contentView、backgroundView、selectedBackgroundView、multipleSelectionBackgroundView层次关系
- UITableView 代理方法调用顺序
//根据 indexPath 以动画的形式取消选中。调用此方法不会造成委托接受tableView:willDeselectRowAtIndexPath和tableView:didDeselectRowAtIndexPath:
//消息;不给UITableViewSelectionDidChangeNotification通知观察者;调用此方法不会产生任何滚动到取消行。
UIKIT_EXTERN NSNotificationName const UITableViewSelectionDidChangeNotification;
// 设置是否显示cell自带的自动排序控件
@property (nonatomic) BOOL showsReorderControl;
//UITableViewCell重排
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath;
复制代码
- [UITableViewRowAction 删除按钮等的定制]
- [多行cell同时编辑]
- [UITableViewIndexSearch 表格的牵引数组中的放大镜]
- [cell 重新排列、跨section排列]
- [UITableViewFocusUpdateContext 焦点更新的上下文]
- [iOS 11 UITableView变化]
- 不等高cell 缓存?
- [局部刷新、高度估算]
- [Copy/Paste 三个代理方法]
//复制的时候三个方法必须被实现
- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(5_0);
- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender NS_AVAILABLE_IOS(5_0);
- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender NS_AVAILABLE_IOS(5_0);
复制代码
---UITableView一些优化点----
- [cell、UITableViewHeaderFooterView的重用机制]
- UITableView+FDTemplateLayoutCell 不等高cell第三方
- 优化UITableViewCell高度计算的那些事 附源码
- [iOS 8 self-sizing cell UITableViewAutomaticDimension]
self.tableView.estimatedRowHeight = xxx;
self.tableView.rowHeight = UITableViewAutomaticDimension;
复制代码
- UITableView之局部刷新的正确使用姿势
- [UITableView之局部刷新 通过事物CATransaction消除隐式动画]
- UITableViewDataSourcePrefetching 预加载特性
- [异步绘制 YYAsyncLayer AsyncDisplayKit]
- 为什么设置了view的Opaque性能会提高(GPU)
GPU会通过图层一和图层二的颜色进行图层混合,计算出混合部分的颜色,最理想情况的计算公式如下:
R = S + D * ( 1 – Sa )
当UIView的opaque属性被设为YES以后,按照上面的公式,也就是Sa的值为1,这个时候公式就变成了:
R = S
即不管D为什么,结果都一样。
因此GPU将不会做任何的计算合成,不需要考虑它下方的任何东西(因为都被它遮挡住了),而是简单从这个层拷贝。
这节省了GPU相当大的工作量。由此看来,opaque属性的真实用处是给绘图系统提供一个性能优化开关!
复制代码
- [Cell中的view尽可能不要使用透明]
- [使用Quartz2D 进行圆角绘制]
- iOS 保持界面流畅的技巧
3. UICollectionView:UIScrollView、UICollectionViewCell、UICollectionViewController、UICollectionViewFlowLayout、UICollectionViewLayout、UICollectionViewTransitionLayout
1.1 在创建UITableView的时候,使用的是- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style用于判断是普通还是分组,
1.2 UICollectionViewLayout实际的作用是一样的,是用来设置cell的布局的,初始化collectionView的时候,一定要给他设置这个属性,否者不会显示。
UICollectionViewFlowLayout是UICollectionViewLayout的子类,给collectionView赋值的时候,一定要使用** UICollectionViewFlowLayout**初始化。
1.3 UICollectionViewFlowLayout和UICollectionViewLayout的关系就像是UIGestureRecognizer和UITapGestureRecognizer的一样。
一个是父类,一个是子类。使用的时候都用子类
复用的时候,首先头尾view要继承于
UICollectionReusableView,然后注册(分为nib和class两种)
UICollectionViewCell也是继承自UICollectionReusableView,UICollectionViewCell : UICollectionReusableView
UIKIT_EXTERN NSString *const UICollectionElementKindSectionHeader NS_AVAILABLE_IOS(6_0);
UIKIT_EXTERN NSString *const UICollectionElementKindSectionFooter NS_AVAILABLE_IOS(6_0);
UIKIT_EXTERN const CGSize UICollectionViewFlowLayoutAutomaticSize NS_AVAILABLE_IOS(10_0);
复制代码
注册supplementary view时,还需要额外指定一个称为类型字符串kind string的附加标志符。
layout负责定义各自支持的补充视图种类。例如,UICollectionViewFlowLayout支持两种补充视图:section header、section footer。为了识别这两种类型视图,flow layout定义了UICollectionElementKindSectionHeader和UICollectionElementKindSectionFooter字符串常量。
在布局时,集合视图将包括类型字符串和其它布局属性的layout发送给数据源,数据源使用类型字符串kind string和重用标志符reuse identifier决定出列视图
复制代码
---这些api详解都少了Drag & Drop--
- UICollectionView.h文件
标准的UICollectionView包含三个部分,它们均需要是UICollectionReusableView的子类:
1. Cells 用于展示内容的主体,对于不同的cell可以指定不同尺寸和不同的内容,这个稍后再说
2. Supplementary Views 追加视图 如果你对UITableView比较熟悉的话,可以理解为每个Section的Header或者Footer,用来标记每个section的view
3. Decoration Views 装饰视图 这是每个section的背景,比如iBooks中的书架就是这个
typedef NS_ENUM(NSUInteger, UICollectionElementCategory) {
UICollectionElementCategoryCell,
UICollectionElementCategorySupplementaryView,
UICollectionElementCategoryDecorationView
};
复制代码
- UICollectionView API详解
- UICollectionViewCell.h 和UITableViewCell的层级结构类似
- UICollectionViewLayout详解,文档翻译
- UICollectionViewLayoutInvalidationContext
1. UICollectionViewLayoutAttributes : NSObject
定义一些frame、size、transform等基础布局信息属性
2. UICollectionViewUpdateItem : NSObject
An object that describes a ***single change*** to make to **an item** in a collection view.
You do not create instances of this class directly.
When updating its content, the collection view object creates them and passes them to the layout object’s “prepareForCollectionViewUpdates: method”,
which can use them to prepare the layout object for the upcoming changes.
当collection view的数据源发生插入、删除、移动变化时,UICollectionView会创建UICollectionViewUpdateItem类的实例,
并发送给layout的prepareForCollectionViewUpdates:方法,layout会为即将到来的布局变化作出准备。你不需要创建该类的实例。
3. UICollectionViewLayoutInvalidationContext : NSObject
当UICollectionView调用invalidateLayoutWithContext:方法重新布局的时候配置该参数,指定哪些cell需要重新布局,
invalidateLayoutWithContext方法使原来的layout失效
通过Invalidation Context指明布局发生改变的部分,使那些布局真正发生改变的部分无效来提升布局性能。
当你自定义一个UICollectionViewLayout子类时,你可以调用invalidationContextClass方法来返回一个你定义的UICollectionViewLayoutInvalidationContext的子类,
这样你的Layout子类在失效时会使用你自定义的InvalidationContext子类来优化更新布局。
4. UICollectionViewLayout : NSObject
5. UICollectionViewLayout (UISubclassingHooks)
6. UICollectionViewLayout (UIUpdateSupportHooks)
7. UICollectionViewLayout (UIReorderingSupportHooks)
复制代码
UICollectionViewLayout
UICollectionViewLayout有3个分类,它们的大概作用如下:
@interface UICollectionViewLayout (UISubclassingHooks) 这个扩展类中,都是用来布局UIcollectionView子视图的
@interface UICollectionViewLayout (UIUpdateSupportHooks) 用来布局删除插入动作
@interface UICollectionViewLayout (UIReorderingSupportHooks) 移动动作布局
在更新数据源时,按照以下步骤操作:
1. 更新数据源中数据。
2. 调用UICollectionView方法进行插入、删除、移动section或item操作。
UICollectionViewLayout可以说是UICollectionView的大脑和中枢,****它负责了将各个cell、Supplementary View和Decoration Views进行组织,为它们设定各自的属性****,包括但不限于:
位置
尺寸
透明度
层级关系
形状
等等等等…
Layout决定了UICollectionView是如何显示在界面上的。在展示之前,一般需要生成合适的UICollectionViewLayout子类对象,并将其赋予CollectionView的collectionViewLayout属性。
复制代码
-
UICollectionViewFlowLayout : UICollectionViewLayout,UICollectionViewTransitionLayout : UICollectionViewLayout API
-
Collection View Programming Guide for iOS 官方文档
---Drag & Drop部分 UICollectionView (UIDragAndDrop)---
跨 App 的 Drag and Drop 只能在 iPad 上使用,iPhone 只支持 App 内的 Drag and Drop。
iOS 11增加了系统范围的拖放操作drag and drop,让用户可以快速简单的将文本、图像和文件从一个app移动到另一个app,
只需轻点并按住即可提取其内容,拖放到其它位置。
复制代码
- [UICollectionView (UIDragAndDrop) API]
- UICollectionView及其新功能drag and drop 非常好
----上面API部分,下面为使用----
- 自定义 Collection View 布局 Objc中国
- Drag & Drop
UIDragItem、UIDragSession、UIDropSession、UIDragInteraction、UIDropInteraction
Drag 的对象是我们平时所接触的 UI 控件,UILabel,UIImageView,或者自定义的 View。让控件可拖动,只需要给控件添加 UIDragInteraction 对象
单指长按某个 View 时,如果添加了 UIDragInteraction,Drag 即刻启动,进入 itemsForBeginningSession 的回调,
这个方法中出现的三个类,关系也十分简单。一个 UIDragInteraction 可以包含多个 UIDragSession,每个 UIDragSession 又可以包含多个 UIDragItem。
UIDragItem 则是 Drop 时接收方所受到的对象。
UIDragItem 包含一个 NSItemProvider 对象,NSItemProvider 对象则包含一个 id 对象。
protocol NSItemProviderWriting 则定义了 UIDragItem 中所包含的数据最后以何种形式提供个 Drop 方
复制代码
- WWDC 2017 iOS11 新特性 Drag and Drop 解析
- Introducing Drag and Drop
- [UICollectionView 自定义布局]
- [UICollectionView + UIKit Dynamics]
- [UICollectionViewLayoutInvalidationContext 优化布局更新效率]
- [copy/paste]
- [item 移动]
- [插入删除items、sections]
- [数据预加载@protocol UICollectionViewDataSourcePrefetching ]
4. UIPageControl、UIPageViewController
PageViewController像电子书那样,一页之中可以放几个childViewcontroller, 然后左右翻,当前frame显示几个viewcontroller。
UIPageControl配合scrollView是用于左右滑动翻页的,当前frame只显示一个viewcontroller。
复制代码
- UIPageViewController的初介绍 ---API
- UIPageViewController教程
- IOS开发 PageViewController和UIPageControl
5. UINavigationBar、UIBarButtonItem、UIToolbar、UINavigationItem、UINavigationController
UINavigationController(导航控制器)是一个容器控制器,其内部展示着多个UIViewController(视图控制器)的内容,
我们可以通过UINavigationController的view属性获取到其自身的视图,
在该视图上有一个位于界面顶部的UINavigationBar(导航栏)和位于界面底部的默认隐藏的UIToolbar(工具栏), 以及一个位于界面中间部分的UIViewController的view
UINavigationController负责创建、配置及管理UINavigationBar,
其通过位于UIViewController堆栈栈顶位置的UIViewController的navigationItem属性(该属性位于UIViewController的UINavigationControllerItem类目中)来管理UINavigationBar展示的内容,
同时UINavigationController也提供了navigationBar属性, 允许开发者通过该属性设置UINavigationBar的外观
UINavigationBar设置navigationBar的外观,UINavigationItem设置UINavigationBar展示的内容
// 侧滑返回手势识别器
@property(nonatomic, readonly) UIGestureRecognizer *interactivePopGestureRecognizer;
复制代码
- UINavigationController API
- 自定义UINavigationBar样式
- UINavigationController与UINavigationBar详解
- [UIToolbar]
在 Navigation 集成 UISearchController
把你的UISearchController赋值给navigationItem,就可以实现将UISearchController集成到 Navigation.
复制代码
6. UITabBarController、UITabBar、UITabBarItem
UITabBarController和UINavigationController一样是用来管理试图控制器的,
与导航控制器不同,tabBarController控制器使用数组管理子试图控制器的,并且子试图之间是平等关系,
导航控制器所管理的试图控制器之间是在出桟和入桟的关系;
复制代码
- UITabbarController,UITabbar
- iOS 自定义 UITabBar 的样式
7. UISearchBar、UISearchContainerViewController、UISearchController、UISearchDisplayController
- UISearchBar 属性、方法详解及应用(自定义搜索框样式)
- UISearchBar实现
UISearchBar的视图层次结构:
''; tintColor = UIDeviceRGBColorSpace 1 0.5 0 1; gestureRecognizers = ; layer = >
| >
| | >
| | ''; clipsToBounds = YES; opaque = NO; layer = >
| | | <_UISearchBarSearchFieldBackgroundView: 0x7fb658419960; frame = (0 0; 0 0); opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = >
复制代码
- UISearchController详解
- [UISearchDisplayController has been replaced with UISearchController]
** UISearchController是iOS 8** 之后推出的一个新的控件, 用于创建搜索条, 及管理搜索事件,
使用这个, 我们可以很容易的创建属于自己的搜索框,
复制代码
8.需要知道的其它控件
- UIMenuController
- UIPopoverController
- UIPresentationController 替代上面的UIPopoverController
- [第三方DXPopver]
iOS8.0开始推荐使用UIPopoverPresentationController,用于替代UIPopoverController。
UIPopoverPresentationController的使用方法类似于UIPopoverController,但是前者可以同时在iPhone和iPad上使用,这一点很不错。
UIPopoverPresentationController并不是控制器类,而是继承自NSObject,不能直接被弹出
复制代码
- UISplitViewController
- UIActivityIndicatorView 系统自带小菊花
Socket(GCDAsyncSocket、WebSocket、SIOSocket)
- iOS 使用 socket 即时通信(非第三方库)
- 深入浅出Cocoa iOS网络编程之Socket
- CocoaAsyncSocket
- BSD socket
Git、SVN、CocoaPods
---CocoaPods---
- [ruby、gem、rvm]
- 用CocoaPods做iOS程序的依赖管理 唐巧
- CocoaPods安装方法-2018.03.27
- 2017最新CocoaPods安装
- CocoaPods 更新安装权限问题
- 教你一步步用CocoaPods创建远程私有库
- Cocoapods使用私有库中遇到的坑
- [rm ~/Library/Caches/CocoaPods/search_index.json]
----Git-----
- 常用 Git 命令清单
- Git常用命令整理
- GUI for git|SourceTree|入门基础
- 深入理解学习Git工作流(git-workflow-tutorial)
- [Pull Requests]
- git rebase
- [集中式工作流、功能分支工作流、Gitflow工作流、Forking工作流]
1.集中式工作流
小红:
ssh user@host
git init --bare /path/to/repo.git
git status # 查看本地仓库的修改状态
git add # 暂存文件
git commit # 提交文件
git push origin master
小黑:
git clone ssh://user@host/path/to/repo.git
git status # 查看本地仓库的修改状态
git add # 暂存文件
git commit # 提交文件
git pull --rebase origin master
git push origin master
如果有冲突:
git add
git rebase --continue
git push origin master
冲突解决不了:
git rebase --abort
2.功能分支工作流
小明:
git checkout -b marys-feature master
git status
git add
git commit
git push origin marys-feature
在Git GUI发起一个Pull Request
其他人同意向master push
git checkout master #切换回master
git pull #拉取当前master确认最新
#pull == fetch+merge
git pull origin marys-feature #将marys-feature分支合并到master
git push origin master #push到中央仓局master
3.Gitflow工作流
#历史分支
Gitflow工作流使用两个分支来记录项目的历史。master分支存储了正式发布的历史,而develop分支作为功能的集成分支。
#功能分支
每个新功能位于一个自己的分支,这样可以push到中央仓库以备份和协作。
但功能分支不是从master分支上拉出新分支,而是使用develop分支作为父分支。当新功能完成时,合并回develop分支。 新功能提交应该从不直接与master分支交互。
#发布分支
一旦develop分支上有了做一次发布(或者说快到了既定的发布日)的足够功能,就从develop分支上checkout一个发布分支。
新建的分支用于开始发布循环,所以从这个时间点开始之后新的功能不能再加到这个分支上—— 这个分支只应该做Bug修复、文档生成和其它面向发布任务。
一旦对外发布的工作都完成了,发布分支合并到master分支并分配一个版本号打好Tag。 另外,这些从新建发布分支以来的做的修改要合并回develop分支。
使用一个用于发布准备的专门分支,使得一个团队可以在完善当前的发布版本的同时,另一个团队可以继续开发下个版本的功能。
这也打造定义良好的开发阶段(比如,可以很轻松地说,『这周我们要做准备发布版本4.0』,并且在仓库的目录结构中可以实际看到)
#维护分支
维护分支或说是热修复(hotfix)分支用于给产品发布版本(production releases)快速生成补丁,这是唯一可以直接从master分支fork出来的分支。
修复完成,修改应该马上合并回master分支和develop分支(当前的发布分支),master分支应该用新的版本号打好Tag
#示例
太多了不写了:注意发布分支release和hotfix分支与master和develop分支合并后删除
Gitflow工作流中Pull Request的使用过程:
当一个功能、发布或是热修复分支需要Review时,开发者简单发起一个Pull Request, 团队的其它成员会通过Bitbucket收到通知。
新功能一般合并到develop分支,而发布和热修复则要同时合并到develop分支和master分支上。 Pull Request可能用做所有合并的正式管理。
4.Forking工作流
Forking工作流是分布式工作流,充分利用了Git在分支和克隆上的优势。可以安全可靠
地管理大团队的开发者(developer),并能接受不信任贡献者(contributor)的提交。
Forking工作流和前面讨论的几种工作流有根本的不同,这种工作流不是使用单个服务端仓库作为『中央』代码基线,而让各个开发者都有一个服务端仓库。
这意味着各个代码贡献者有2个Git仓库而不是1个:一个本地私有的,另一个服务端公开的。
Forking工作流的一个主要优势是,贡献的代码可以被集成,而不需要所有人都能push代码到仅有的中央仓库中。
开发者push到自己的服务端仓库,而只有项目维护者才能push到正式仓库。 这样项目维护者可以接受任何开发者的提交,但无需给他正式代码库的写权限。
其他贡献者fork正式仓库代码,修改后提交到自己的仓库中,给正式仓库发起一个pull request,维护者同意后会push到正式仓库
复制代码
---SVN---
- CornerStone的使用
- svn st 状态详解
- svn命令清单
---Git、SVN异同----
- Git、SVN异同
- 集中式vs分布式
- Git、SVN权限管理问题
Linux
- []
杂项
- iOS基础之顺传逆传传值(delegate、block)
- NSString属性什么时候用copy,什么时候用strong?
- c语言指针
- OC指针的问题 解决了我对OC指针的疑惑
- URI Scheme
- iOS学习——iOS项目Project 和 Targets配置详解
- On-Demand Resources Guide中文版(按需加载资源--上)
- On-Demand Resources Guide中文版(按需加载资源--下)
- iOS开发之Settings Bundle的使用
- CocoaPods 都做了什么?
- Xcode8兼容iOS7以及低版本Xcode调试高版本iOS系统
越狱开发+反编译
- 看雪论坛
- 国内逆向论坛
- iOS越狱开发指南
- [app启动时间优化??????]
- iOS 应用如何防止被反编译
- Objective - C 进行代码混淆
- iOS 防止反编译加密方法
RAC
1. 'RACSiganl:RACStream':信号类,只是表示当数据改变时,信号内部会发出数据,它本身不具备发送信号的能力,而是交给内部一个订阅者去发出。
2. 'RACSubscriber':表示订阅者的意思,用于发送信号,这是一个协议,不是一个类,只要遵守这个协议,并且实现方法才能成为订阅者。通过create创建的信号,都有一个订阅者,帮助他发送数据。
3. 'RACSubject' : RACSignal:信号提供者,由于继承RACSignal(信号类)+实现接口RACSubscriber(订阅者),所以自己可以充当信号,又能发送信号
------
'冷热信号':
冷信号是被动的,只会在被订阅时向订阅者发送通知;热信号是主动的,它会在任意时间发出通知,与订阅者的订阅时间无关。
也就是说冷信号所有的订阅者会在订阅时收到完全相同的序列;而订阅热信号之后,只会收到在订阅之后发出的序列。
热信号的订阅者能否收到消息取决于订阅的时间。
在 ReactiveCocoa 中,我们使用RACSignal来表示冷信号,也就是每一个订阅者在订阅信号时都会收到完整的序列;RACSubject用于表示热信号,订阅者接收到多少值取决于它订阅的时间。
RACSubject 的实现并不复杂,它『可变』的特性都来源于持有的订阅者数组 subscribers,在每次执行 subscribeNext:error:completed: 一类便利方法时,都会将传入的 id 对象加入数组:
RACSubject 会在自身接受到这些方法时协议中的方法,下发给持有的全部的 subscribers。
RACBehaviorSubject 和RACReplaySubject,前者在订阅时会向订阅者发送最新的消息,后者在订阅之后可以重新发送之前的所有消息序列。
4. 'RACBehaviorSubject'最重要的特性就是在订阅时,'向最新的订阅者发送之前的最新消息',这是通过覆写 -subscribe: 方法实现的。
RACBehaviorSubject,它在内部会保存一个currentValue对象,也就是最后一次发送的消息:
在每次执行 -sendNext: 时,都会对 RACBehaviorSubject 中保存的 currentValue 进行更新,并使用父类的 -sendNext: 方法,向所有的订阅者发送最新的消息
5. 'RACReplaySubject' 相当于一个自带 buffer 的 RACBehaviorSubject,它可以在每次有新的订阅者订阅之后发送之前的全部消息。
6. 'RACTuple':元组类,类似NSArray,用来包装值.
7. 'RACSequence:RACStream':RAC中的集合类,用于代替NSArray,NSDictionary,可以使用它来快速遍历数组和字典。
[numbers.rac_sequence.signal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
8. 'RACCommand:NSObject':RAC中用于处理事件的类,可以把事件如何处理,事件中的数据如何传递,包装到这个类中,他可以很方便的监控事件的执行过程。
9. 'RACMulticastConnection:NSObject':用于当一个信号,被多次订阅时,为了保证创建信号时,避免多次调用创建信号中的block,造成副作用,可以使用这个类处理。
**订阅connect.signal,会调用RACSubject的subscribeNext,创建订阅者,而且把订阅者保存起来,不会执行block。**
10. RACScheduler:RAC中的队列,用GCD封装的
11. RACUnit :表⽰stream不包含有意义的值,也就是看到这个,可以直接理解为nil.
12. RACEvent: 把数据包装成信号事件(signal event)。它主要通过RACSignal的-materialize来使用,然并卵。
13 . 处理当界面有多次请求时,需要都获取到数据时,才能展示界面
'rac_liftSelector:withSignalsFromArray:Signals:'当传入的Signals(信号数组),每一个signal都至少sendNext过一次,就会去触发第一个selector参数的方法。
使用注意:几个信号,参数一的方法就几个参数,每个参数对应信号发出的数据。
复制代码
- RAC整体篇
- 最快让你上手ReactiveCocoa之基础篇
- 最快让你上手ReactiveCocoa之进阶篇
- 『可变』的热信号 RACSubject
- iOS-ReactiveCocoa使用之RACCommand
- RAC 中的双向数据绑定RACChannel
- RAC核心元素与信号流
- RAC中用RACChannel实现双向绑定
大侠博客
- 阮一峰
- Casa
- 唐巧
- 猫神
- 结构之法 算法之道
- MrPeak