Oc

Ffmpeg Build 相关

ffmpeg在iOS下的编译(不包括x264,aac的库) 1. 下载gas-preprocessor.pl 下载地址https://github.com/libav/gas-preprocessor 将gas-preprocessor.pl文件拷贝到/usr/local/bin/目录下 chmod 777 /usr/local/bin/gas-preprocessor.pl开启执行权限 2. 安装yasm brew install yasm 3. 下载编译脚本 下载地址https://github.com/applexiaohao/FFmpeg-iOS-build-script,脚本中有下载ffmpeg的操作. 这步也可用x264,fdk-aac编译到ffmpeg中提到的脚本 脚本中要改下SOURCE="ffmpeg-4.0.2"为ffmpeg的版本号我当前为4.0.2. 还需要改下DEPLOYMENT_TARGET="8.0"iOS支持版本. 执行./build-ffmpeg.sh得到FFmpeg-iOS这个文件夹就是我们需要导入的 4. 导入及头文件 导入FFmpeg-iOS文件夹 Header Search Paths中添加$(PROJECT_DIR)/项目名字/FFmpeg-iOS/include 需要的依赖的库如下: VideoToolbox.framework //硬解 AudioToolbox.framework libiconv.tbd libbz2.tbd libz.tbd 编译x264 视频编码用的库 下在x264源码,下载地址http://www.videolan.org/developers/x264.html. 或直接git clone http://git.videolan.org/git/x264.git下载 下载编译脚本https://github.com/kewlbear/x264-ios. 执行脚本./build-x264.sh 如果遇到Out of tree builds are impossible with config.h/x264_config.h in source dir.,需要删除x264中的config.h和x264_config.h 如果编译后只有arm64架构的,则需./build-x264.sh armv7这样编译出其他需要的架构库,之后再./build-x264.sh lipo合成 编译x86_64架构的时候需要先brew install nasm 这样i386架构还是编译出来,因为这个架构已经用到,暂时不纠结 编译faac 音频编码用的库

Swift实现可选协议

Swift实现可选协议 定义 @objc protocol FTMagicMoveTransionFromProtocol { @objc optional func captureView() -> UIView? } 实现 //parent class FTViewController: UIViewController, FTMagicMoveTransionFromProtocol{ func captureView() -> UIView? { return nil } } //child class FTHomeViewController: FTViewController{ override func captureView() -> UIView { return (selectedCell?.thumbImageView)! } }

Swift调用objective-c的framework(非pod)需要注意的

swift调用objective-c的framework(非pod)需要注意的 1. 创建AppName-Bridging-Header,并#import<>相关文件 2. General -> Embedded Binaried添加 3. Build Setting -> Swift Compiler-General -> Objective-C Briding Header 添加header的path,如:FaceTube/FaceTube-Bridging-Header.h 4. Link Binary With Libraries 添加相关framework 再就是可以试试把生成framework的项目拖到自己项目中运行生成framework例如这样 这样之后如果还报错 在link Binary With Libraries中添加libc++.tbd应该可以搞定

UIKit性能优化

Instrument (command+I) 原文地址 Core Animation : Color Blended Layers : 检测哪里发生了图层混合,并用红色标记出来。因此我们需要尽可能减少看到的红色区域。 对于UIImageView来说,不仅它自身需要是不透明的,它的图片也不能含有alpha通道. PS:如果label文字有中文,依然会出现图层混合,这是因为此时label多了一个sublayer,如果有好的解决办法欢迎告诉我。 Color Hits Green and Misses Red : 表示如果命中缓存则显示为绿色,否则显示为红色,显然绿色越多越好,红色越少越好. 光栅化的核心在于缓存的思想。 layer进行光栅化后渲染成位图放在缓存中。当屏幕出现滑动时,我们直接从缓存中读取而不必渲染,所以会看到绿色。当新的label出现时,缓存中没有个这个label的位图,所以会变成红色。第三点比较关键,缓存中的对象有效期只有100ms,即如果在0.1s内没有被使用就会自动从缓存中清理出去 光栅化的缓存机制是一把双刃剑,先写入缓存再读取有可能消耗较多的时间。因此光栅化仅适用于较复杂的、静态的效果。通过Instrument的调试发现,这里使用光栅化经常出现未命中缓存的情况,如果没有特殊需要则可以关闭光栅化 // label.layer.shouldRasterize = true Color Copied Images : 像素在内存中的布局和它在磁盘中的存储方式并不相同。考虑一种简单的情况:每个像素有R、G、B和alpha四个值,每个值占用1字节,因此每个像素占用4字节的内存空间。一张1920*1080的照片(iPhone6 Plus的分辨率)一共有2,073,600个像素,因此占用了超过8Mb的内存。但是一张同样分辨率的PNG格式或JPEG格式的图片一般情况下不会有这么大。这是因为JPEG将像素数据进行了一种非常复杂且可逆的转化。 “Color Copied Images”就用来检测这种实时的格式转化,如果有则会将图片标记为蓝色。 当我们打开JPEG格式的图片时,CPU会进行一系列运算,将JPEG图片解压成像素数据。显然这个工作会消耗不少时间,所以不应该在滑动时进行,我们应该预先处理好图片。 CPU主要处理两件事: 把图片从PNG或JPEG等格式中解压出来,得到像素数据 如果GPU不支持这种颜色各式,CPU需要进行格式转换 Color Misaligned Images : 表示如果图片需要缩放则标记为黄色,如果没有像素对齐则标记为紫色 图片的缩放需要占用时间,因此我们要尽可能保证无论是本地图片还是从网络或取得图片的大小,都与其frame保持一致。 Color Offscreen-Rendered Yellow : 离屏渲染意味着把渲染结果临时保存,等用到时再取出,因此相对于普通渲染更占用资源。 会把需要离屏渲染的地方标记为黄色,大部分情况下我们需要尽可能避免黄色的出现。离屏渲染可能会自动触发,也可以手动触发。以下情况可能会导致触发离屏渲染: 重写drawRect方法 有mask或者是阴影(layer.masksToBounds, layer.shadow*),模糊效果也是一种mask layer.shouldRasterize = true 前两者会自动触发离屏渲染,第三种方法是手动开启离屏渲染 设置阴影的时候要指定path 要不会离屏渲染 设置cornerRadius本身并不会导致离屏渲染,但很多时候它还需要配合layer.masksToBounds = true使用。根据之前的总结,设置masksToBounds会导致离屏渲染。解决方案是尽可能在滑动时避免设置圆角,如果必须设置圆角,可以使用光栅化技术将圆角缓存起来: Color Compositing Fast-Path Blue:

AspectsCocoa

前言 : 本来是想写一个简易高效的rac, 不过在写信号传递的时候没找到好的解决方法,又不想像rac那样在传递的时候不断创建信号,因为要高效嘛.如果大家有啥好的方法麻烦告诉我下QQ466142249,如果发现什么错误,或者某个部分可以有更好的实现也麻烦告诉我下,哈哈哈哈.这里的全部代码在github的这里. 如何使用AspectsCocoa? 添加 : [self.label addObserver:self forSelector:@selector(setText:) withBlock:^(AOPObserverInfo *info,NSString *text){ NSLog(@"text = %@",text); }]; [self.label addObserver:self forSelector:@selector(drawTextInRect:) withBlock:^(AOPObserverInfo *info,NSValue *rectValue){ NSLog(@"rectValue = %@",rectValue); }]; 移除 : [self.label removeObserver:self forSelector:@selector(setText:)]; or [self.label removeObserver:self]; 详细可以参看demo 大概思路 其实和KVO的原理有点相似,衍生出来一个中间类,重写setter方法做到键值监听.不过这里不是只有setter方法还有其他普通的方法.再就是普通方法的变化参数需要好好处理下. 1 . 判断该类是否有这个监听方法 (这里我就直接取这个方法的类方法和实例方法,如果都不存在,则抛出异常) 2 . 判断是否生成过中间类,没生成则生成一个 3 . 查看中间类是否有要监听的方法,没有添加方法 (有关于普通方法的变参问题,我这里是用va_list来处理的) 4 . 储存监听信息和回调 具体实现 1 . 判断该类是否有这个监听方法 Method method = class_getInstanceMethod([self class], selector); if (!