Unruly的博客

心存善念,必有善行;善念善行,天必佑之。


  • 首页

  • 归档

  • 标签

  • 分类

  • 关于

拾遗 - Runtime

发表于 2018-07-01 | 分类于 拾遗

使用场景

  • 关联对象 Associated Objects
  • 消息发送 Messaging
  • 消息转发 Message Forwarding
  • 方法调配 Method Swizzling
  • “类对象” NSProxy Foundation | Apple Developer Documentation
  • KVC、KVO About Key-Value Coding

第三方

  1. Acpects(AOP必备,“取缔” baseVC,无侵入埋点)
  2. MJExtension(JSON 转 model,一行代码实现 NSCoding 协议的自动归档和解档)
  3. JSPatch(动态下发 JS 进行热修复)
  4. NullSafe(防止因发 unrecognised messages 给 NSNull 导致的崩溃)
  5. UITableView-FDTemplateLayoutCell(自动计算并缓存 table view 的 cell 高度)
  6. UINavigationController+FDFullscreenPopGesture(全屏滑动返回)

拾遗 - OC语言特性

发表于 2018-06-30 | 分类于 拾遗

动态性(Dynamic)

  • - 动态类型
    • 指的是对象指针类型的动态性、具体是指使用id任意类型将对象的类型确定推迟到运行时
    • 动态类型识别 isKindOfClass
  • - 动态绑定
    • 核心是在运行时动态的为类添加属性和方法
    • 消息传递机制
  • - 动态加载
    • 动态资源加载
    • 可执行代码模块的加载

成员变量和属性

属性:成员变量+setter+getter

Category(类别/分类/类目)

应用场景

  • 多人维护同一个类
  • 为已经存在的类添加方法
  • 声明私有方法
  • 模拟多继承
  • 把frameowork的私有方法公开

注意

  • 分类只能添加方法 不能增加成员变量
  • 分类同名的方法会覆盖原来的方法(原来的方法还有只是在顺序列表的后面)
  • 分类方法中不可以调用super
  • 相同方法的优先级 分类(最后编译的分类优先)-> 原类 -> 父类
  • 分类是runtime时加载 不是编译时
  • 分类可通过runtime 关联对象 添加属性(类别中添加@property描述的属性,(只会生成这个属性的set,get方法的声明,也就不是会实现.)这时候编译是没问题的没警告没报错,但是一旦在创建对象后为属性赋值或者使用这个属性的时候,程序就崩溃了,奔溃的原因也很简单,就是找不到属性的set/get方法)

Extension(扩展)

  • 为一个类添加额外的原来没有变量,方法和属性
  • 一般的类扩展写到.m文件中
  • 一般的私有属性写到.m文件中的类扩展中

Category 和 Extension 区别

  • Class Extension 在编译期就会将定义的 Ivar、属性、方法等直接合入主类,而 Category 在程序启动 Runtime Loading 时才会将属性(没 Ivar)和方法合入主类
  • Class Extension 是匿名的 Category
  • 主要的区别在于,对于扩展,编译器将期望您在主@implementation中实现方法,而对于类别,您有一个单独的@implementation块

Delegate

使用weak 防止循环引用

NSNotification

观察者模式

KVO(Key-value observing)

观察者模式

实现原理

Apple 使用了 isa 混写(isa-swizzling)来实现 KVO 。当观察对象A时,KVO机制动态创建一个新的名为:NSKVONotifying_A 的派生类,并将被观察对象的isa 指向这个派生类,该类继承自对象A的本类,且 KVO 为 NSKVONotifying_A 重写观察属性的 setter 方法,setter 方法会负责在调用原 setter 方法之前和之后,通知所有观察对象属性值的更改情况。
(备注: isa 混写(isa-swizzling)isa:is a kind of ; swizzling:混合,搅合;)

注意

必须继承NSObject 因为NSObject可监听值的变化 NSKeyValueObserving

KVC(Key-value Coding)

  • 动态set、get
  • 访问私有属性
  • KVC和Objc的runtime组合可以很容易的实现Model和字典的转换
  • KVO是基于KVC实现的

Sepc Repo

发表于 2018-06-26

创建私有 Sepc Repo

CocoaPods对于一名iOS开发来说再熟悉不过了,它的工作原理就是在GitHub上面有个Spec Repo,它里面包括成千上万的podspec文件索引目录。然后我们在项目集成的时候可以通过它去找到我们需要的开源代码。其实CocoaPods的Spec Repo就是一个中介。

  • The Specs Repo is the repository on GitHub that contains the list of all available pods. Every library has an individual folder, which contains sub folders of the available versions of that pod.

创建私有 Spec Repo,然后把我们公共组件的podspec文件放在里面,然后集成的时候让CocoaPods帮我们集成那我们就能达到目的

私有 Spec 仓库需要在 git 托管平台托管,现有的免费私有仓库有 Coding、CSDN 以及自己搭建 Gitlab,本文选用 Gitlab 托管平台演示如何进行组件化开发。

进入 ./cocoapods/repos 查看已经存在的spec repo

  • cd ./cocoapods/repos
  • ls -l

在私有git服务器上创建自己的sepc repo

  • 创建项目 获取访问地址 https://git.xxx.cn/TestSpecs.git
  • 终端执行 pod repo add [本地名字] https://git.xxx.cn/TestSpecs.git
  • ls -l 或者 pod repo list 查看

创建Pods仓库

详见 CocoaPods建立自己的Podspec

验证通过后 提交podspec 到私有spec repo

  • pod repo push [本地名字] xx.podspec
    成功后 在目录 ./cocoapods/repos 查看

集成测试

  • pod search xx
  • 创建项目测试
  • - pod install 如果[!] Unable to find a specification for xx 因为默认是去公有的索引库查找
    • 解决: 增加两个source # 表示先去找私有,再找公有
    • source ‘https://git.xxx.cn/TestSpecs.git'
    • source ‘https://github.com/CocoaPods/Specs.git'
  • pod lib lint时 私有库中含有私有库 索引不到 需要添加 –sources=’私有仓库地址,https://github.com/CocoaPods/Specs.git'
  • search 失败 可能同名覆盖 或者移除搜索映射:rm ~/Library/Caches/CocoaPods/search_index.json
  • pod update xx

命令

  • git status
  • 更新 repo: pod repo update REPO_NAME
  • git clean -f

Development Pod

参考:

官方文档: Private Pods

iOS 知识小集(1)

发表于 2018-06-11 | 分类于 知识小集

struct - class

在类中,当你对一个变量进行拷贝的时候,两个变量都指向内存中的同一个对象。两个中的任何一个变量中的改变都会影响另外一个变量(引用类型)。然而在结构体中,你是通过创建了一个新的对象(值类型)来实现简单的拷贝和复制的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
struct StructPerson {
var name: String
}
class ClassPerson: NSObject {
var name: String = ""
init(name: String) {
self.name = name
}
}
class MMStruct_ClassController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let class_p = ClassPerson(name: "yanming")
print(class_p.name)
let new_class_p = class_p
new_class_p.name = "mengqi"
print(class_p.name)

let struct_p = StructPerson(name: "father")
print(struct_p.name)
var new_struct_p = struct_p
new_struct_p.name = "mother"
print(struct_p.name)

/* 输出结果
yanming - mengqi - father - father
*/
}
}

拾遗 - UIKit

发表于 2018-06-07 | 分类于 拾遗

UIView 和 CALayer

联系

在每一个UIView实例当中,都有一个默认的支持图层layer,UIView负责创建并且管理这个图层。实际上 UIView之所以能够显示,就是因为它里面有这个一个层,才具有显示的功能 ,UIView仅仅是对它的一层封装,实现了CALayer的delegate,提供了处理事件交互的具体功能,还有动画底层方法的高级API。可以说CALayer是UIView的内部实现细节

  • UIView 是CALayer轻量级封装 使用CALayer不会带来显著的性能优势 iOS MacOS CALayer无缝衔接

区别

  • 首先UIView可以响应事件,CALayer不可以响应事件
  • 一个 Layer 的 frame 是由它的anchorPoint,position,bounds,和 transform 共同决定的,而一个 View 的 frame 只是简单的返回 Layer的 frame
  • UIView主要是对显示内容的管理而 CALayer 主要侧重显示内容的绘制
    在做
  • iOS 动画的时候,修改非 RootLayer的属性(譬如位置、背景色等)会默认产生隐式动画,而修改UIView则不会。

图像显示原理

分工

  • CPU:计算视图frame 输出位图
  • CPU:绘制纹理、图层渲染
  • 结果放到帧缓存区(frame buffer)
  • 再由视频控制器根据vsync信号在指定时间之前去提取帧缓冲区的屏幕显示内容

卡顿分析

  • UI渲染时间过长
  • 计算过多,主线程阻塞,无法渲染UI界面
  • 网络请求慢 UI层无响应
  • 总结 <60fps 1/60 如果CPU和GPU加起来的处理时间超过了16.7ms,就会造成掉帧甚至卡顿

CPU资源消耗分析

  • 对象创建:主线程创建对象、读取文件等
  • 对象调整:frame、bounds、transform及视图层次等属性调整很耗费CPU资源。尽量减少不必要属性的修改,尽量避免调整视图层次、添加和移除视图
  • 布局计算:autolayout 提前算好布局
  • 文本渲染、图片解码:当用UIImage或CGImageSource创建图片时,图片数据并不会立刻解码。图片设置到UIImageView或CALayer.contents中去,并且CALayer被提交到GPU前,CGImage中的数据才会得到解码。这一步是发生在主线程的,并且不可避免。
  • - SD_WebImage处理方式:在后台线程先把图片绘制到CGBitmapContext中,然后从Bitmap直接创建图片
  • 图像绘制

CPU资源消耗分析

  • 纹理混合:尽量减少短时间内大量图片的显示,尽可能将多张图片合成一张进行显示。
  • 视图混合:尽量减少视图层次和数量,并在不透明的视图里标明opaque属性以避免无用的Alpha通道合成。
  • 图形生成:尽量避免离屏渲染,尽量采用异步绘制,尽量避免使用圆角、阴影、遮罩等属性。必要时用静态图片实现展示效果,也可尝试光栅化缓存复用属性

拾遗 - 计算机网络

发表于 2018-06-06 | 分类于 拾遗

web服务器

Apache、Tomcat、JBoss、Nginx

  • 硬件部分,一个网络服务器是一台存储了网络服务软件以及网站的组成文件(比如,HTML文档、图片、CSS样式表和JavaScript文件)的计算机。它接入到互联网并且支持与其他连接到互联网的设备进行物理数据的交互。
  • 软件部分,网络服务器包括控制网络用户如何访问托管文件的几个部分,至少他要是一台HTTP服务器。一台HTTP服务器是一种能够理解URL(网络地址)和HTTP(浏览器用来查看网页的协议)的软件。通过服务器上存储的网站的域名(比如mozilla.org)可以访问这个服务器,并且他还可以将他的内容分发给最终用户的设备。

OSI七层协议
应用层、表示层、会话层、传输层、网络层、数据链路层、物理层

CDN

内容分发网络。CDN是构建在网络之上的内容分发网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN的关键技术主要有内容存储和分发技术

应用层

DNS、HTTP、HTTPS所在的层为应用层、浏览器会将应用层的包交给下一层去完成,通过 socket 编程实现

传输层

两种协议

  • 无连接的协议UDP
  • 面向连接的协议TCP
  • - 会保证这个包能够到达目的地、如果不能到达、重新发送直至到达
    • 所谓的建立连接,是为了在客户端和服务端维护连接,而建立一定的数据结构来维护双方交互的状态
    • 可靠交付:无差错、不丢失、不重复
    • 面向数据流
    • 是可以用拥塞控制的
    • 是一个有状态服务
    • 总结:顺序问题、丢包问题、连接维护、流量控制、拥塞控制

TCP和UDP区别

通俗地讲TCP就是有脑子的,里面精确地记着发送了没有,接收到没有,发送到哪个了,应该接收哪个了,错一点儿都不行。而UDP则是无状态服务。通俗地说就是没脑子,天真无邪的,发出去就发出去了。

UDP应用场景

  • 需要资源少,在网络情况比较好的内网,或者对于丢包不敏感的应用
  • 不需要一对一沟通,建立连接,而是可以广播的应用
  • 需要处理速度快,时延低,可以容忍少数丢包,但是要求即便网络拥塞,也毫不退缩

网页或者APP的访问、流媒体协议、实时游戏、loT物联网、移动通讯领域

TCP

连接三次握手,断开四次挥手

网络层

IP协议:机器IP和目标的服务器IP地址

MAC层

网关 路由协议

总结

  • IP是地址,有定位功能(公网和私有);MAC是身份证,无定位功能
  • CIDR
  • DHCP协议主要是给用户租用IP地址,和房产中介很像,要商谈、签约、续租,广播还不能抢单
  • DHCP协议能给客户推荐‘装修队’PXE,能安装系统(云计算领域)

Sever

发表于 2018-06-06

正向代理、反向代理、透明代理

正向代理 - Forward Proxy

正向代理(forward)是一个位于客户端【用户A】和原始服务器(origin server)【服务器B】之间的服务器【代理服务器Z】,为了从原始服务器取得内容,用户A向代理服务器Z发送一个请求并指定目标(服务器B),然后代理服务器Z向服务器B转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理。如下图:

正向代理

正向代理 就是 代理服务器替代访问方【用户A】去访问目标服务器【服务器B】

正向代理主要作用

  • 访问本无法访问的服务器(科学上网)
  • Cache-缓存技术(Cache命中)
  • 客户端访问授权(内网访问,如下图)
    过滤外网
  • 隐藏访问者的行踪(肉鸡)

总结

正向代理是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端必须设置正向代理服务器,当然前提是要知道正向代理服务器的IP地址,还有代理程序的端口。

反向代理 - Reverse Proxy

反向代理正好与正向代理相反,对于客户端而言代理服务器就像是原始服务器,并且客户端不需要进行任何特别的设置。客户端向反向代理的命名空间(name-space)中的内容发送普通请求,接着反向代理将判断向何处(原始服务器)转交请求,并将获得的内容返回给客户端。

反向代理主要作用

  • 保护和隐藏原始资源服务器(如下图)
    限制访问
  • 负载均衡(如下图)
    负载均衡

总结

反向代理结论与正向代理正好相反,对于客户端而言它就像是原始服务器,并且客户端不需要进行任何特别的设置。客户端向反向代理的命名空间(name-space)中的内容发送普通请求,接着反向代理将判断向何处(原始服务器)转交请求,并将获得的内容返回给客户端,就像这些内容原本就是它自己的一样。

透明代理

透明代理的意思是客户端根本不需要知道有代理服务器的存在,它改编你的request fields(报文),并会传送真实IP。注意,加密的透明代理则是属于匿名代理,意思是不用设置使用代理了

作用

  • 公司内的行为管理软件

高效工具

发表于 2018-04-12

Xcode

  • shift + command + o 弹出快速查找文件窗口
  • shift + command + j 定位到文件所在目录
  • command + t/w 新建/关闭一个Tab
  • command + alt + 左右 收缩代码
  • control + i 缩进
  • command + n新建文件 command+shift+n 新建工程
  • command + alt + [/] 上移/下移

其他

  • 编辑器 多行编辑 shift + command + L
  • shift + command + 3全图截屏
  • shift + command + 4自选区域截图
  • command + F3 快捷查看桌面

iTerm2 - 终端利器

快捷键

命令 说明
command + d 垂直分屏
command + shift + d 水平分屏
command + ; 查看历史命令
ctrl + u 清除当前行
command + shift + h 查看剪贴板历史
ctrl + u 清除当前行
ctrl + a 到行首
ctrl + e 到行尾
ctrl + p 上一条命令
ctrl + r 搜索命令历史
command + r 清屏

Hexo - 快速、简洁且高效的博客框架

命令

  • hexo generate -> 生成静态文件
  • hexo deploy -> 部署网站
  • hexo server -> 启动服务器
  • hexo server -p xxxx 重设端口
  • ctrl + c 取消

通用命令

lsof -i:8080 -> 查看8080端口号占用
kill -9 xxxx -> kill进程

JavaScript- WXS

发表于 2018-04-08

JavaScript 一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标准通用标记语言下的一个应用)网页上使用,用来给HTML网页增加动态功能。

《《JavaScript 高级程序设计》》 《《JavaScript 权威指南》》

阅读全文 »

WXML、WXSS

发表于 2018-04-07

WXML - 语言特性

  • 数据绑定
  • 列表渲染
  • 条件渲染
  • 模板引用
阅读全文 »
1234
Unruly

Unruly

40 日志
4 分类
71 标签
GitHub 微博
Links
  • kalman
© 2016 — 2019 Unruly
由 Hexo 强力驱动
|
主题 — NexT.Gemini v5.1.4