Enki's Notes


  • 首页

  • 分类

  • 归档

  • 标签

  • 关于

iOS 静态库中的 Category 运行时错误

发表于 2017-09-13 | 分类于 开发笔记 | 阅读次数

最近在弄 iOS 下的音视频 SDK 的移植和适配,该 SDK 是基于 WebRTC 项目但并未使用官方的 ninja 编译脚本,而是使用的 cmake 作为编译工具。在 WebRTC 的音频模块中引用了一个 UIDevice 的 Category 来做设备类型的判断,编译和链接都没有出现问题,但在运行时出现了 selector not recognized 的异常。该异常可以从我之前的 《iOS 运行时之消息转发机制》 文章中了解到,由于对象接收到了一个无法处理该 selector ,经过消息转发后还未得到处理,会在 doesNotRecognizeSelector 方法中抛出的异常。

Category 以及一些其他的工具类被编译在一个基础的静态库中,在音频模块中引用该静态库,除了 Category 代码其他所有的代码都能正常编译、链接以及运行,但唯独 Category 在运行时出现了错误,由于 Category 的 Objective-C 语言的特性,最开始我以为需要为编译器添加针对 Category 的参数,找了很久也没找到针对 Category 特性的编译参数,无奈之下只好求助 stackoverflow ,最终找到了根本原因和解决方法。

阅读全文 »

WebRTC 的丢帧策略

发表于 2017-07-29 | 分类于 音视频/WebRTC | 阅读次数

最近在弄一个 Android 平台下远程桌面项目,是基于 WebRTC 框架实现的,由于平台限制,芯片是用的特定厂商的芯片,桌面采集以及 H264 硬编码都是芯片厂商提供方案,能够有很好性能表现。在将桌面的采集以及 H264 的编码库整合到 WebRTC 框架中时,发现的存在画面延时的问题,于是对 WebRTC 的编解码框架的源码进行了分析,了解到 WebRTC 的两个特性。

在 WebRTC 中有很多可以控制视频帧率和码率的行为,这里介绍一下当视频采集过快以及编码器输出码率过高时,WebRTC 主动丢帧的策略。这里采集过快是指视频采集的速度大于编码器处理的速度。例如视频采集线程每秒采集 30 帧,而编码线程每秒只能处理 15 帧,这时候就出现了采集过快或者说是编码器太慢。编码器输出码率过高,是指编码器的输出码率大于设定的最高输出码率值,例如设置编码器码率为 1024kbps,而实际产生的码率是 1500kbps 这时候就出现了输出码率过高的情况。本文主要介绍上述两种情况下 WebRTC 是如何实现丢帧行为的。

阅读全文 »

iperf 的介绍和使用

发表于 2017-06-06 | 分类于 知识整理/总结 | 阅读次数

iperf 是一个网络性能测试工具,做服务开发或者测试的同学,接触的可能比较多。因为最近有用到这个工具,并且这个工具做的非常不错,这里记录一下工具的使用方法。iperf 是个开源并且跨平台的软件,代码托管在 GitHub 上,可以从 Releases 找到各个发行版本,也可以去 官网 下载各个平台的版本。 使用 iperf 时,需要分别运行服务端和客户端,在测试是最好保证两个端的软件版本一致,这样会免去一些没必要的麻烦。

下载好后,可以先在本机做一个简单的回环测试,结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 运行服务端
$ ./iperf -s
------------------------------------------------------------
Server listening on TCP port 5001
TCP window size: 128 KByte (default)
------------------------------------------------------------
[ 4] local 127.0.0.1 port 5001 connected with 127.0.0.1 port 54817
[ ID] Interval Transfer Bandwidth
[ 4] 0.0-10.0 sec 35.1 GBytes 30.1 Gbits/sec
# 运行客户端
$ ./iperf -c 127.0.0.1
------------------------------------------------------------
Client connecting to 127.0.0.1, TCP port 5001
TCP window size: 144 KByte (default)
------------------------------------------------------------
[ 4] local 127.0.0.1 port 54817 connected with 127.0.0.1 port 5001
[ ID] Interval Transfer Bandwidth
[ 4] 0.0-10.0 sec 35.1 GBytes 30.1 Gbits/sec
阅读全文 »

Dnsmasq 介绍与使用

发表于 2017-05-23 | 分类于 知识整理/总结 | 阅读次数

上一个星期在查找一个设备无法解析公司内部域名的问题,最终查出来问题是在网关设备上运行的 Dnsmasq 服务没有正确的配置上游 DNS 服务器,导致内网域名无法被正常的解析。在这期间对 DNS协议 又重新学习了一番,并且对 Dnsmasq 服务有了一些了解,结合网上一些资料,对 Dnsmasq 提供的 DNS 和 DHCP 服务的配置做一些总结和备忘。

Dnsmasq 是一个开源的项目,可以在 thekelleys 上找到最新版本和源码,它能提供 DNS 、DHCP、TFTP、PXE 等功能。Dnsmasq 的 DNS 服务工作原理是,当接收到一个 DNS 请求是, Dnsmasq 首先会查找 /etc/hosts 文件,如果没有查找到,会查询本地 DNS 缓存记录,如果还是未找到对应的记录,则会将请求装发到 /etc/resolv.conf 文件中定义的上游 DNS 服务器中,从而实现对域名的解析。

基于上述原理,我们可以在 /etc/hosts 文件中添加本地内网的域名解析,从而实现本地内网的域名解析。同时我们还可以使用 Dnsmasq 来为一些特定的域名指定 DNS 服务器,或者阻止某些域名的访问。由于 Dnsmasq 会缓存上游 DNS 服务的查询记录,从而可以提高访问过的网址的连接速度。

默认情况下,Dnsmasq 会从 /etc/dnsmasq.conf 读取配置项,我们也可以使用 -C 的启动参数来指定配置文件。下面介绍一下常用的 DNS 和 DHCP 服务的配置参数。

阅读全文 »

WebRTC iOS&OSX 库的编译

发表于 2017-05-12 | 分类于 知识整理/总结 | 阅读次数

安装 Depot_tools

  • git 命令获取 depot_tools:
1
$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
  • 配置坏境变量
1
2
$ echo "export PATH=$PWD/depot_tools:$PATH" > $HOME/.bash_profile
$ source $HOME/.bash_profile
  • 检测配置是否成功
1
$ echo $PATH

安装 ninja

阅读全文 »

iOS 运行时之消息转发机制

发表于 2017-04-21 | 分类于 知识整理/总结 | 阅读次数

今天写一篇老生常谈的话题 —— Objective-C 的消息转发机制。Objective-C 下所有的方法调用都可以理解为,给一个对象发送一个消息。一个对象接收到消息后,会从当前类的方法列表或者父类的方法列表查找到对应的方法实现(IMP)来处理该消息。大致流程如下:

  1. 通过 NSObject 的 isa 指针找到对应的 Class
  2. 在 Class 的方法列表中找到对应的 selector
  3. 如果在当前 Class 中未能找到 selector 则往父类的方法列表中继续查找
  4. 如果能找到对应的 selector 则去执行对象的方法实现(IMP)

在上述流程中如果不能找对对应的 selector 时,这时候就会进入消息转发机制。消息转发机制可分为两个阶段,在这两个阶段中,有 3 次机会来处理之前未能处理 selector,越往后所花费的代价将越大,处理的灵活程度也就越高。如下图所示:

消息转发流程

阅读全文 »

iOS 运行时之 Associative(关联)

发表于 2017-02-18 | 分类于 知识整理/总结 | 阅读次数

iOS 下有很多运行时特性,这里介绍一下 Associative(关联) 这个运行时特性,以及它一些使用场景。Associative 意思为关联,能够将两个对象建立一种关系。这种关系是一种 从属 关系,也就是说有一个 关联者 和一个 被关联者。比如说我们可以将一个 NSString 对象关联到一个 UIView 对象上。这里的 NSString 对象就是 被关联者, UIView 对象就是 关联者。

在 objc/runtime.h 文件中,找到 Associative 相关的 API 定义,如下:

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/**
* Sets an associated value for a given object using a given key and association policy.
*
* @param object The source object for the association.
* @param key The key for the association.
* @param value The value to associate with the key key for object. Pass nil to clear an existing association.
* @param policy The policy for the association. For possible values, see “Associative Object Behaviors.”
*
* @see objc_setAssociatedObject
* @see objc_removeAssociatedObjects
*/
OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0);
/**
* Returns the value associated with a given object for a given key.
*
* @param object The source object for the association.
* @param key The key for the association.
*
* @return The value associated with the key \e key for \e object.
*
* @see objc_setAssociatedObject
*/
OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key)
OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0);
/**
* Removes all associations for a given object.
*
* @param object An object that maintains associated objects.
*
* @note The main purpose of this function is to make it easy to return an object
* to a "pristine state”. You should not use this function for general removal of
* associations from objects, since it also removes associations that other clients
* may have added to the object. Typically you should use \c objc_setAssociatedObject
* with a nil value to clear an association.
*
* @see objc_setAssociatedObject
* @see objc_getAssociatedObject
*/
OBJC_EXPORT void objc_removeAssociatedObjects(id object)
OBJC_AVAILABLE(10.6, 3.1, 9.0, 1.0);
阅读全文 »

Protocol Buffer 简介与使用

发表于 2017-02-17 | 分类于 知识整理/总结 | 阅读次数

Protocol Buffer(简称Protobuf或PB)是由 Google 开发的,原本用来解决索引服务器的请求、响应协议,后面才对外使用和开源的,它是一种数据交换格式,与 XML 和 JSON 相比 ,它是一种二进制格式,避免了各种文本格式转换的问题,并且更体积更小、速度更快使用更简单方便,还自带部分数据压缩功能,在网络传输时可以减少数据流量。同时它也是与平台和语言无关的,尤其在网络数据交换方面,使得它越来越流行。

Protobuf 是一个开源项目,项目托管在 GitHub 上,链接为:https://github.com/google/protobuf,源码包含两部分内容:

  • PB基础库:用来完成对象模型与数据模型之前的转换
  • PB编译器:源码生成器,用来将 .proto 文件转换成对应语言的对象模型的源码

Protobuf 截止目前最新版本为 3.2.0-alpha-1 版本,在 3.0.0 版本之前也就是 2.6.1 版本时官方只支持 C++/Java/Python 三种语言,3.0.0 版本之后才逐步支持其他语言。在这之前如果其他语言需要用到 Protobuf 都是通过第三方扩展来实现的,目前官方以及支持以下编程语言:

阅读全文 »

HTTP 之 Content-Type

发表于 2016-08-29 | 分类于 开发笔记 | 阅读次数

在移动端开发中 HTTP 协议经常被用到,但是在面试或者工作中问到客户端和服务器传输业务数据,使用的数据的封装格式是什么以及怎么被封装到 HTTP 协议中时,很少有人能讲明白。

在移动开发中 HTTP 协议为客户端到服务器端,提供了一条数据通道,能够将我们的业务数据传输到服务器,并且从服务器上获取响应数据。在 HTTP 协议头中的 Content-Type 字段描述了 HTTP 的 BODY 体的数据格式,而在 BODY 中可以定义我们业务数据的数据格式。Content-Type 字段可以用很多种类型,具体有哪些可以看 这里,并且也可以根据自身业务来自定义,不过这种做法比较少。这次我主要讲解三种格式分别为 application/x-www-form-urlencoded、application/json 以及 multipart/form-data,其他的格式可以自己理解。

下面给各位吃瓜群众介绍上述三种格式在 GET 和 POST 两种请求方法中的区别,为了更直观的看到我们的数据的组织方式,我使用了 Charles 来进行抓包分析。

阅读全文 »

两则开发小笔记

发表于 2016-07-22 | 分类于 开发笔记 | 阅读次数

好久没有写博客了,介绍一下项目中一个 Core Graphics 绘制图片时的效率优化方法,以及记录一下 GCDAsyncSocket 框架在读取网络数据要注意的一个点。

Core Graphics 绘图性能对比

Core Graphics 框架为我们提供了 2D 绘图能力,在使用 Core Graphics 绘制图片时,不同的实现方法使得渲染图片的效率有很大差异,下面是提供两种不同实现方式的对比,看看 Core Graphics 在绘制图片时效率上的差异。

测试方法为自定义一个 UIView,重写- (void)drawRect:(CGRect)rect 方法,在该方法中使用 Core Graphics 方式绘制图片。然后在开启一个定时器不断的调用 - (void)setNeedsDisplay; 方法来计算绘图所使用的时间。

阅读全文 »
123
Enki

Enki

说过很多潇洒的话,做过很多打脸的事

28 日志
5 分类
35 标签
RSS
GitHub
© 2019 Enki
由 Hexo 强力驱动
主题 - NexT.Mist
本站总访问量 次 本站访客数 人次