开发小技巧
文章平均质量分 76
朗清风
iOS开发工程师
展开
-
NSArray类簇
NSArray 类簇NSArray, NSMutableArray类簇(class clusters)是抽象工厂模式在iOS下的一种实现,试图将多个类的实现统一在一起,对外只暴露简单的使用接口,隐藏类的真实实现。iOS中的NSArray,NSDictionary,NSArray以及NSNumber中都使用了这种实现。这里主要看一下数组的大概实现注: 以下数据使用64位模拟器演示.NSArray, NSMutableArray在iOS中,NSArray, NSMutableArray的实现中包含了很多原创 2021-01-10 22:29:23 · 489 阅读 · 0 评论 -
NSPredicate使用小总结
NSPredicate的使用为什么要使用NSPredicate?NSPredicate的使用场景MatchContainsBeginsWith && EndsWithLikeInNot逻辑运算符号为什么要使用NSPredicate?在做应用实现的过程中,经常会遇到一些筛选符合条件数据的需求,对于普通人来说,设计出一个筛选速度很快的算法并不是一件容易的事.所以iOS内部将这些实现进行了封装,便于友好地支持开发者的使用,降低使用的难度,加快开发的进程.NSPredicate的使用场景NS原创 2020-12-08 10:45:39 · 907 阅读 · 0 评论 -
优化if-else结构
优化if-else结构去除完全不必要的else模块价值分配提前语句检查将if-else转化为字典结构扩展应用程序if-else是日常使用较多的语法结构,但是正确使用if-else却并不是一件简单的事情,需要保证所有的逻辑都被包括且处理逻辑不会出现重叠,在一定程度上会导致设计复杂,代码的可读性差,并且可能会导致重构困难。事实上,对于else结构更应该关注的是不同场景下的实现,而不是如果进行场景划分。在很多if-else结构中,并不需要将所有的场景都进行列举,只需要将需要单独处理的场景进行特殊处理即可.这样就原创 2020-11-27 14:41:04 · 239 阅读 · 0 评论 -
为不同父类的所有类添加同一属性
在面向对象开发中,经常会遇到给某一些符合条件的类添加共同属性的,使得这些类的所有的对象都具有该属性的需求。一般来讲可以通过类的继承来实现这一需求,但是如果需要添加属性的类并不继承自同一父类,或者继承自同一系统类,但并不直接继承自同一个自定义类,通过在父类中添加属性让子类继承的实现就变得不够现实,这时就可以利用运行特性结合协议来实现.场景:需要为应用中的每一个控制器都添加一个tag属性用来标记各个不同的控制器。首先为UIViewController添加协议:@protocol UIViewContr原创 2020-11-26 10:24:59 · 258 阅读 · 0 评论 -
Category同名函数如何调用原来实现
Category中是原生开发中经常用到的一个技术实现,利用这一技术可以在不知道原始类实现的情况的情况下未类添加属性和方法实现,可以很好对类功能进行扩展.Category加载OC最重要的特性就是运行时,而Category之所以与众不同就在于其加载也是在运行时.在程序加载时内核会通过dyld将machO文件加载到内存进行解析,然后通过_objc_init来进行应用的初始化._objc_initvoid _objc_init(void){ //使用静态变量确保该方法不会被重复执行原创 2020-06-02 17:33:37 · 1397 阅读 · 0 评论 -
微信分享出现 未认证应用
微信在2019年年底更新了sdk使用universal link进行应用间回调传值,并在2020年年初呼吁开发者更新,同时声明在3.30之后开始对使用旧版本微信sdk的应用开始标注"未认证应用",并在6.1之后逐步限制旧版本sdk的使用.然而很多开发者在更新完sdk之后神奇的发现,新版本的sdk在进行分享时依然会出现"未认证应用"标注但分享功能登录等功能并不受影响.这样的开发者很多,比如鄙人我.在认真核对了微信给出的开发文档之后并做了测试之后发现:基本可以确定这就是微信内部认证的逻辑问题.对于unive原创 2020-06-02 12:32:53 · 4973 阅读 · 0 评论 -
如何防止应用意外崩溃(一)
如论是全栈大神,还是普通程序猿,都不能规避掉所有的异常,所以只要是人写的程序都有意外奔溃的可能,更何况操作系统本身就可能会包含一些意想不到的异常情况.随着开发经验和阅历的增加,由于自身能力问题导致的异常情况会越来越少.但异常不可避免,而应用闪退又是一种极其糟糕的用户体验,所以应该尽可能地减少甚至消除这些异常导致的闪退现象.今天重点讨论一下关于unrecognized selector sent to instance 0x......的处理.这是一个经常会遇到的异常,造成这个异常的情况的原创 2020-05-13 20:21:01 · 1027 阅读 · 0 评论 -
通讯录中的特殊字符
绝大多数注册类应用都会选择使用手机号作为用户的注册的账号,由于键盘上有限的字符基本都是常用的手动输入的手机号的合法性比较容易控制.但是如果用户选择粘贴的复制的方式就会混进来一些特殊的字符造成判断上的异常.在iPhone XS Max13.4.1操作系统上,复制通讯录时会发现看到的和粘贴之后的内容不一样....原创 2020-05-06 21:13:56 · 1772 阅读 · 0 评论 -
Block 签名信息的使用
Block在OC中却是一个非常神奇的存在,即具备了对象的特性(具备isa指针),又具备了方法的特性(具有自己的实现函数),这就自然而然注定了Block会与众不同.除了常规使用之外,还可以利用Block做一些"骚操作".Block签名在OC中中所有的方法都有编码信息,签名信息包含了方法的参数类型和返回值类型等信息.对于对象的实例方法可以利用 Method method =...原创 2020-04-27 16:53:13 · 840 阅读 · 0 评论 -
如何在OC中没有显示声明的方法?
在OC中调用方法时,可以直接使用显式//NSMutableArray调用array类方法NSMutableArray *arr = [NSMutableArray array];//NSMutableArray对象调用addObject方法[arr addObject:@"element"];经常会需要执行没有显示声明的方法,比如动态添加的方法,私有方法等,这些方法都不能使用...原创 2020-04-14 16:16:17 · 518 阅读 · 0 评论 -
网页和原生代码的交互----WKWebView
我们了解和h5和原生代码交互的原理之后,现在我们尝试解析由h5发送出来的请求中的方法名和参数。原创 2016-09-20 10:04:21 · 652 阅读 · 0 评论 -
网页和原生代码的交互----UIWebview
虽然使用原生的代码书写功能可以使应用的功能更加稳定,用户体验更佳完美,但是由于原生代码书写功能会受到审核时间相对较长,灵活性不足,页面不精彩的因素的限制,近些年来,很多的开发者都在致力于开发出来易于改写,方便发布,完成及时性页面修改等功能的语言脚本,方法和框架,比如React,React-native以及cordova框架等。 现在我们就从基本的交互开始,来研究一下不使用第三方的框架原创 2016-09-19 16:04:31 · 3061 阅读 · 0 评论 -
NSString的语义属性为什么是copy
在声明语义属性时,一般会将NSString的语义属性声明为copy而不是一般对象使用的strong,这是为什么呢?深拷贝与浅拷贝在高级语言中,这是一个经常使用到的概念,也是在实际使用中很容易出错的一个概念.深拷贝就是以原来的对象为模版重新开辟了空间,生成了一个新的对象,与原来的对象的不在同一个内存单元中. 浅拷贝是指重新生成了一个指针,指向了原来对象对应的内存空间,所以并没有生成新的...原创 2020-01-14 17:27:49 · 240 阅读 · 0 评论 -
内存对齐原则
内存在使用过程并不是单一的依次排列,而是按照某种既定的规则来进行对齐,以方便快速访问.内存的对齐原则有以下三条:数据成员对齐:成员根据其自身大小,从自身大小的整数倍内存地址(以第一个元素存储在0位置为参考)开始存储; 结构体成员对齐:如果包含了结构体成员,则结构体成员的存储位置从其内部成员最大值的整数倍地址开始存储; 结构体总大小对齐:必须要是其内部最大成员的整数倍,不足的要补齐.注:以...原创 2019-12-23 18:49:26 · 2570 阅读 · 2 评论 -
共用体与位域
C语言中除了结构体,还有一种很重要的结构,叫做共用体(Union).共用体定义共用体(Union)是C语言中一个特殊的数据类型,可以在相同的内存位置存储不同的数据类型,可以定义一个或者多个成员变量的共用体,但是在指定时刻,只能有一个成员变量的值是完整的有效值.union [union tag]{ member definition; member definition;...原创 2020-01-13 14:22:35 · 1681 阅读 · 0 评论 -
OC运行时简单运用----获取类中未暴露的属性
作为iOS 开发人员,几乎所有人都或多或少听过说OC很牛逼的一个机制-运行时机制,然而对于很对人来讲在实际的开发过程中用到运行时使用场景貌似并不是很多,原因很多,比如运行时几乎是纯C的底层API,对于很多没有C语言基础的开发者来说阅读和使用并不顺畅,或者项目中使用到的技术并不经常涉及这方面的应用。其实,很多运行时的机制在日常的开发过程中,如果应用得当,会给你的开发过程带来很多意想不到的便利...原创 2016-02-24 11:00:57 · 1023 阅读 · 1 评论 -
OC运行时简单运用----动态添加属性
在开发过程中,如果经常会遇到想要给现有的类(闭源类)添加自己的属性标志的需求,如果使用继承会显得麻烦和臃肿,但是category又不支持直接添加属性,这时候我们就可以利用运行时的特性来解决这一问题。2.1 实现原理在运行时中,存在一个可以为对象动态绑定属性的方法:void objc_setAssociatedObject(id object, const void *key, id...原创 2016-03-04 14:20:29 · 759 阅读 · 2 评论 -
ipa文件上传
随着Xcode功能的不断升级,逐渐开始出现体积臃肿,启动缓慢的问题,所以在增加新功能的同时Xcode开始优化删减掉一些不太常用或者不太有必要的功能.在最新的Xcode(11.x)中,Application Loader就被不幸中招,从Xcode中被删除掉.Xcode supports uploading apps from the Organizer window or from the c...原创 2019-11-11 16:38:41 · 947 阅读 · 0 评论 -
iOS 12.0+系统录屏(一)
iOS在录屏功能是走过了长长的一段路,在其他平台尤其是直播平台日益火爆的推动下,iOS12.0终于开放在应用中唤起系统录屏权限给开发者.以下内容以iOS 12.0+为基础,不再讨论之前的版本.理论准备了解ReplayKit框架以及了解一下iOS9.x,iOS10.x,iOS11.x以及iOS12.x上录屏权限以及api的不同; 了解App Group内存共享实现; 了解CFNot...原创 2019-11-05 19:43:31 · 6388 阅读 · 9 评论 -
iOS Crash异常日志收集
异常日志的产生与存储任何一款应用在使用过程中出现各种异常问题在所难免,如何能快速还原场景定位异常,对于能否及时修复问题非常重要.在apple的文档中我们发现了这样一张图,完整地描述了应用的整个流程:编译器将源代码编译成机器代码的过程中,会生成调试符号,这些调试符号将生成的二机制文件中的每一条机器指令映射回源代码行.根据调试信息格式的构建设置(setting builds--Debug...原创 2019-10-14 12:13:54 · 569 阅读 · 0 评论 -
iOS Crash异常日志符号化
异常日志符号化一般情况下如果我们可以通过Xcode来查看异常日志的话,获取到的异常日志都是符号化之后,可以直接查看并定位异常.但是如果在测试阶段需要从手机上导出异常日志,或者集成了第三方异常收集但是未能上传符号表到对应的后台等情况下就只能获取到未符号化的异常日志,这时候就需要对异常日志进行符号化.生成符号表文件的前提想要进行异常日志的符号化,前提就是保存了打包时生成的.dSYM文件,...原创 2019-10-14 12:11:18 · 554 阅读 · 0 评论 -
iOS 13.x获取通讯录信息时的注意事项
之前的项目兼容的版本在iOS9.0以上,所以在项目中使用了CNContacts框架获取用户的通讯录信息,大致的实现如下:/// 判断字符串是否可用/// 辅助函数/// @param str 原始对象BOOL isAvailableString(NSString *str) { if ([str isKindOfClass:[NSNull class]]) { ...原创 2019-10-11 11:08:16 · 3262 阅读 · 0 评论 -
Aspects框架------源码分析
目录2.1 判断是否符合进行下一步交换操作的条件2.2创建AspectsContainer容器类2.3创建AspectIdentifier对象保存hook内容2.4 把AspectIdentifier根据options添加到对应的数组中2.5 进行hook操作上次聊到了Aspects的基本使用,这次我们来聊一下Aspects的基本实现原理.Aspects对外提供了...原创 2019-08-09 11:10:15 · 379 阅读 · 0 评论 -
Aspects框架------汲取
之前我们聊过关于Aspects源代码解析,今天简单聊一聊这个类库中我们可以学习到那些实用的开发技巧.3.1如何获取block签名在apple最新的开源代码中我们可以找到关于block的定义:// Values for Block_layout->flags to describe block objectsenum { BLOCK_DEALLOCATING = ...原创 2019-08-09 14:53:04 · 260 阅读 · 0 评论 -
获取线上应用信息(坑点)
获取线上应用信息有两个接口可以使用:https://itunes.apple.com/lookup?id={appid} https://itunes.apple.com/cn/lookup?id={appid}有帖子说在国内建议使用第二个链接,在国外建议使用第一个链接,就目前使用情况没有看到两个接口有太大的区别,不放心的话可以两个都调用一下.坑点虽然iOS的应用不建议用户...原创 2019-10-10 11:10:14 · 1069 阅读 · 0 评论 -
控制器self.view坑
在iOS开发中,如果视图想要显示,除非需要显示的视图有充分的理由显示在window(例如将要显示的视图层级很搞,或者不太方便添加到控制器视图上时)之外,一般情况下会选择将视图通过添加自视图的方式直接或者间接添加到控制器的根视图上.这里就有一个经常会掉进去的坑点.场景一般情况下,我们会选择在视图根视图加载完成之后才添加子视图,也就是在viewDidLoad中添加子视图:- (voi...原创 2019-09-30 12:50:36 · 860 阅读 · 0 评论 -
iOS中常见的锁
由于线程共享了进程的资源空间,如果是多线程读写资源,就会出现同时对同一资源进行操作的情况,这样就会发生数据的读写错乱和不一致现象.为了保持数据的一致性,不至于出现多个线程同时修改相同资源的情况,我们需要为资源操作进行加锁处理,在一个线程访问资源时,对该资源进行加锁,确保在同一时间只有一个线程对资源进行操作,当线程对资源的操作结束之后,对该资源解除锁定,允许下一个线程对资源进行访问.我们以景点...原创 2019-09-25 19:43:32 · 186 阅读 · 0 评论 -
控制任务的执行顺序的常用技术
在多线程开发中,我们经常会利用到多线程的特性并发执行功能,用以提高执行的效率。那么在这种并发执行中如何来控制特定任务的执行顺序呢?1. 使用栅栏函数栅栏函数可以在指定的队列中设置障碍,来阻碍后续任务的执行,从而达到控制执行顺序的目的.假设有四个任务,我需要任务三在任务一,任务二完成之后执行,任务四在任务三完成之后执行: dispatch_queue_t queue = dis...原创 2019-08-27 09:54:10 · 476 阅读 · 0 评论 -
栅栏函数
多线程技术最大限度地使用了多核CPU的性能,也极大地提升了任务执行的效率。但是在很多情况下,我们期待能够在并行的任务中,设置有些任务之间的依赖,而使用栅栏函数就很好的一种实现方式.1 栅栏函数是个啥?栅栏函数是GCD提供的用于阻塞分割任务的一组函数。就像其定义一样,其主要作用就是在队列中设置栅栏,来人为干预队列中任务的执行顺序.常用的栅栏函数有两个dispatch_barrier_asy...原创 2019-08-21 15:21:03 · 1184 阅读 · 0 评论 -
JSPatch 框架 (一)
话说很久以前,iOS审核需要很久的时间,随随便便一周起,所以紧急的bug修复,时间紧迫的功能更新等都会受到审核时间的影响,iOSer默默承受了许多无端的指责,众人渴望能够出现一个可以让我们在需要的时候随时可以进行应用更新,而不用再受限制于各种各样的审核规则,于是大神bang的JSPatch横空出世,润泽了无数双充满期待的眼神.这篇文章我们先简单聊聊如何JSPatch如何使用.以下使用场景基于JSP...原创 2019-08-16 09:26:34 · 248 阅读 · 0 评论 -
AFNetworking的图片缓存(一)
AFN经常用来做数据请求类,使用SDWebImage做图片加载,而事实上AFN有封装了一套关于图片加载的接口,只是用的人不是很多,可能觉得SD更加专业吧.今天我们来窥探一下AFN关于图片加载的实现逻辑.AFAutoPurgingImageCacheAFAutoPurgingImageCache服从了AFImageRequestCache协议,这个协议主要定义了用来处理网络图片资源的内存缓...原创 2019-08-20 17:26:41 · 329 阅读 · 0 评论 -
Block 基本使用介绍
block在iOS中是一个神奇的存在,既像是面向过程的函数又像是面向对象的对象实例,实质上是一个匿名函数.如果能够很好的利用它就就可以很方面地控制数据流程,使代码结构更加清晰,逻辑实现更加明了易读.1 如何定义一个block直接在使用的地方定义例如我们需要一个没有返回值没有参数的block:如果参数为空,后边的()可以省略.void (^blockWithNoValueAndPa...原创 2019-08-14 11:31:38 · 644 阅读 · 0 评论 -
ObjC中的TypeEncodings
OC中有一个经常使用到的概念叫做类型编码(type encodings).这个编码规则在方法的类型编码以及类型的动态动态转化中都有着非常重要的作用.1. ObjC 的 type encodings 列表编码 意义 c char 类型 i int 类型 s short 类型 l long 类型,仅用在 32-bit 设备上 q long...原创 2019-08-13 16:48:54 · 399 阅读 · 0 评论 -
支付宝h5版本如何返回原始应用
支付宝是经常需要集成的第三方支付工具,主要的集成方式有两种:使用原生sdk:功能相对稳定,交互更加友好; 使用h5网页版:更加灵活,不依靠应用更新.在大多数情况下,如果是应用内的支付功能,我们会选择使用原生的sdk版本进行集成,这样的话功能稳定用户体验更加友好.但事实上很多情况下我们不得不使用网页版本,例如:应用由于某种原因不能及时更新; 产品需求比较着急,时间上不允许; ...原创 2019-07-25 19:57:46 · 2602 阅读 · 0 评论 -
NSArray你不一定不知道的冷知识
1.NSArray是不是单例?这个问题乍一看好像很可笑,数组当然不是单例!但是真的所有数组都不是单例吗?下边我们来看一组有意思的验证:从上述验证中,可以发现:使用alloc方法创建出来的NSArray对象指向了同一个内存空间,虽然看起来怪怪的,但是它真的是单例; init初始化之后的对象变成了另一个空间地址,而且所有对象都指向了同一个空间地址,说明对于类簇为了提升效率节约不必要...原创 2019-07-11 11:09:56 · 335 阅读 · 0 评论 -
iOS 图片压缩
图片对象是在开发过程中经常需要处理的对象之一,经常需要对图片进行压缩处理,而如何快速高效地处理图片数据,是我们应该关心的重要问题之一.在实际开发中,我们压缩图片的手段主要有两种,一种是压缩图片的质量,另一种是压缩图片的质量.1.压缩图片的质量.1.1 压缩图片质量的原因节约存储空间:存储空间有限或者价格比较昂贵等原因导致没有足够的存储空间去储存图片; 加快传输速度,提升用户体验...原创 2019-07-25 19:41:42 · 656 阅读 · 0 评论 -
SKStoreReviewController 使用中的坑
应用中都或多或少地会引导用户去进行应用评论,常用的方法大概有以下几种:(1)使用deep link。在app地址链接后边拼接上action=write-review可以直接跳转到App Store应用中对应的应用评价界面进行评价..(2) 使用SKStoreReviewController。在iOS10.3之后,iOS 提供了一种新的评价方式,可以不用跳转出应用在应用内就完成应用的星级...原创 2019-06-26 11:36:51 · 6692 阅读 · 3 评论 -
NSURLCache使用(一)------基本使用
在项目中,经常会遇到这样的问题:有时候会发现某个接口一旦出错,即使服务器没有问题,这个接口也会在一段时间内持续报错,而服务器却并没有收到相关的接口请求; 明明数据已经更新了,移动端却一直在使用旧的数据,怎么刷新都不能很好的同步; 其他可能涉及到网络缓存的异常,而你却明明什么都没做上面的问题多数都跟网络缓存有关系,或许你会奇怪明明你什么都没做,哪里来的缓存?今天我们就来聊聊这个默默在起作用...原创 2019-08-27 16:29:13 · 501 阅读 · 0 评论 -
Aspects框架------使用
目录1.1 什么是AOP?1.2 Aspects如何使用?1.3虽然不想说,但是总有同学会问,为啥我hook类的方法就不会成功呢?难道这个著名的框架就只能hook实例方法吗?1.4 使用Aspects需要注意的问题1.1 什么是AOP?开发中总会遇到这样的需求,需要对某一个类的所有方法进行统一的操作,例如需要统计用户在每个控制器中停留的时间,大概的实现方法有但不限于...原创 2019-08-06 16:00:35 · 3930 阅读 · 1 评论 -
Block 捕获变量的实现原理之基本数据类型变量
之前的文章我们谈过关于C语言结构体的一些知识,借助于这些知识我们来看一下OC中关于Block的内部实现原理.1. Block基本知识1.1 Block的内部实现在apple开源的objc源代码中,我们找到了关于Block实现的一些细节:// Values for Block_layout->flags to describe block objectsenum { ...原创 2019-08-31 13:53:52 · 219 阅读 · 0 评论