IT技术博客大学习 共学习 共进步

iOS开发

共 64 篇文章

IT 2016-02-11 14:55:28 / 累计浏览 2,287

深入理解RunLoop

这篇讲的是 iOS/macOS 系统中至关重要的事件循环机制——RunLoop。作者从 CFRunLoop 的开源源码出发,带我们看清了这个底层对象的真实面貌。 文章不止于概念,而是层层深入:解释了 RunLoop 与线程一对一的绑定关系,剖析了 Source(事件源)、Timer、Observer 这三个核心组件的区别与协作,特别是区分了需要手动唤醒的 Source0 和能主动唤醒线程的 Source1。对于 Mode 的机制讲解也十分关键,说明了 RunLoop 每次运行只能处理特定模式下事件的设计意图。 最实用的部分在于,文章详细拆解了苹果是如何基于这套机制来实现自动释放池、触摸事件分发、屏幕刷新(CADisplayLink)、定时器等日常功能的。最后,通过分析 AFNetworking 和 AsyncDisplayKit 这两个经典框架的用法,展示了 RunLoop 在高性能网络监听和界面异步渲染中的巧妙应用,让理论立刻有了落脚点。 通篇将源码逻辑与系统设计结合,不仅解释了“是什么”,更阐明了“为什么这么实现”,对于想穿透 API 层、理解 iOS 系统运行原理的开发者来说,是一次扎实的源码导览。

IT 2016-02-11 14:54:53 / 累计浏览 1,608

iOS 处理图片的一些小 Tip

这篇讲的是 iOS 开发中几个容易被忽略的图片处理细节,作者从实际编码经验出发,给出了不少实用技巧。 比如保存 GIF 动图,直接用 UIImageWriteToSavedPhotosAlbum 会转码成 PNG,正确做法是通过 ALAssetsLibrary 的 writeImageDataToSavedPhotosAlbum 来保留原始动图格式。保存 UIImage 到磁盘时,用 NSKeyedArchiver 其实是性能最差的方案,对于不含透明像素的图片,用 UIImageJPEGRepresentation(0.9) 压缩保存反而在编码速度和文件体积上都更优。 文章还深入解释了 UIImage 的缓存机制。通过 imageNamed 创建的图片,其解码数据在第一次显示时才会生成,并缓存在全局缓存中,通常只在 App 退后台或收到内存警告时清空。即使使用 imageWithData 创建图片,底层也会启用缓存。想要避免缓存,可以手动调用 CGImageSourceCreateWithData 并关闭缓存参数,或者更常见地,将图片绘制到画布再取出数据——这也是很多网络图片库采用的做法。 此外,文章还介绍了如何直接获取图片解码后的原生数据、快速判断文件图片类型,以及如何利用 CGImageSource 的 Incremental 方式实现像浏览器那样边下载边显示图片的效果,并对比了 PINRemoteImage、YYWebImage 与 SDWebImage 在这方面的实现差异。

IT 2016-02-09 23:04:15 / 累计浏览 2,512

自己动手打造基于 WKWebView 的混合开发框架(三)——设计插件协议以兼容 Cordova

这篇讲的是如何从零构建一个基于 WKWebView 的混合开发框架,并重点实现与 Cordova 插件的完全兼容。作者的目标很明确:让你已有的 Cordova 项目能无缝、无感知地迁移到自研的高性能框架上。 核心思路是打通 JS 与 Native 之间完整的双向数据通道。文章详细拆解了实现过程:首先通过 `window.webkit.messageHandlers` 建立了 JS 到 Swift 的传值与调用机制,并用 Console 插件作为示例。接着,为了解决 Swift 向 JS 的异步回调问题,作者设计了一个基于队列(Queue)的管理系统,每次调用将回调函数压栈并传递序号,Native 处理完再凭序号回调,从而完美复刻了 Cordova 的插件调用模式。 文章的巧妙之处在于,作者没有止步于零散的调用实现,而是进一步抽象设计了统一的 `Plugin` 基础类和插件协议。这个协议规范了 JS 层如何封装调用数据(包含 className、functionName、data 及回调 taskId),以及 Native 层如何统一反射、分发请求并管理回调。这使得新增一个兼容 Cordova 的插件变得结构清晰、流程标准。最终,这套设计被整合为一个名为 BlackHawk 的纯 Swift 开源项目,为追求性能与可控性的团队提供了一个切实可行的 Cordova 替代方案。

IT 2016-02-09 23:02:45 / 累计浏览 2,212

自己动手打造基于 WKWebView 的混合开发框架(二)——js 向 Native 一句话传值并反射出 Swift 对象执行指定函数

这篇讲的是在基于WKWebView的混合开发中,如何让JavaScript(JS)代码直接调用Swift编写的原生功能。作者从WKWebView的一个“屌炸天”的新特性——`window.webkit.messageHandlers`方法出发,演示了JS如何通过`postMessage`这一句话,将字符串甚至JSON对象传递到Native层。 核心的巧妙之处在于,接收到消息后,作者利用苹果开放的runtime接口,通过解析出的类名和方法名字符串,动态反射出Swift对象并执行指定函数。这意味着网页可以按需调用任意预注册的原生方法,极大地增强了混合应用的灵活性。文章提供了从注册消息处理程序、接收数据到最终反射执行的完整代码示例,并配有截图验证了每一步的结果。 作者在此基础上构建了一个名为“BlackHawk”的纯Swift高性能框架,可作为Cordova的替代方案。整个过程将原本可能复杂的跨语言调用,简化为了清晰可循的几步操作。

IT 2016-02-09 23:01:00 / 累计浏览 1,991

自己动手打造基于 WKWebView 的混合开发框架(一)——WKWebView 上手

这篇讲的是如何从零开始,基于 iOS 的 WKWebView 打造自己的混合开发框架。作者从 WKWebView 的优势切入——它解决了 UIWebView 的内存和性能顽疾,将渲染进程交给系统管理,还支持高达 60fps 的刷新和更直接的 JS 通信方式。 文章是典型的“上手指南”风格,手把手教学。它从最基础的代码示例开始,逐步带你完成初始化、加载网页、解决 iOS 9 默认不支持 HTTP 的 bug,再到实现错误处理和 JS 的 alert 弹窗等核心功能。每一部分都配有具体代码和效果截图,特别适合想了解混合开发底层实现的 iOS 开发者参考。 在教程之外,作者还推荐了一个名为 BlackHawk 的开源项目,它是用 Swift 实现的高性能 Cordova 替代方案。如果你对文章里的基础实现感兴趣,这个项目提供了一个更完整的工业级参考。

IT 2016-02-07 14:26:58 / 累计浏览 1,589

iOS JSON 模型转换库评测

这篇评测文章从实际开发需求出发,对 iOS 平台常用的六个 JSON/模型转换库进行了横向对比。评测覆盖了手动转换(Manually)、YYModel、FastEasyMapping、JSONModel、Mantle 和 MJExtension 这几个主流选择。 文章的核心围绕三个维度展开:性能、功能与容错性。在性能测试中,作者使用了两个典型用例(一个简单的 GitHub User 数据,一个复杂的微博数据),给出了直观的耗时对比图表。结论非常明确:YYModel 的性能显著领先,甚至接近手写代码的效率;Mantle 的性能在对比中最弱;JSONModel 和 MJExtension 处于中间水平。功能上,各库各有侧重,比如 FastEasyMapping 支持 CoreData,但使用者较少。 容错性测试则揭示了更实际的开发体验差异。YYModel 和 Mantle 会进行类型检查以避免崩溃,但处理策略不同:前者尝试自动转换并在失败时留空,后者直接终止转换并向上报错,更利于调试。MJExtension 在自动转换失败时可能直接赋值不匹配的类型,存在潜在风险。 总的来说,文章为开发者选择库提供了清晰的参考:追求极致性能可以看 YYModel,注重稳定和调试体验可考虑 Mantle,而 MJExtension 和 JSONModel 则是在功能与易用性上的常见折中选择。

IT 2016-02-07 14:10:46 / 累计浏览 3,609

iOS 保持界面流畅的技巧

这篇深度解析从 iOS 屏幕显示原理入手,剖析了界面卡顿的根源。文章详细拆解了 VSync 机制下,CPU 与 GPU 协同工作的流程,并指出当任一方未能及时完成渲染时,掉帧便会发生。作者系统性地列举了 CPU 侧的对象创建与销毁、布局计算(尤其是 Autolayout 的性能陷阱)、文本渲染等常见开销来源,也涵盖了 GPU 侧的渲染与合成问题。 在剖析原理的基础上,文章重点介绍了 AsyncDisplayKit 框架。作者阐述了其图层预合成、异步并发操作等核心设计,以及如何利用 Runloop 进行任务分发,从而将主线程从繁重的布局和渲染任务中解放出来。 文章更提供了极具实践价值的参考:一个完全仿照微博、Twitter 的开源列表 Demo。通过预排版、预渲染、异步绘制等优化技巧的组合运用,该 Demo 即使在 iPhone 4S 上快速滑动,也能稳定保持 50-60 FPS 的流畅度。这不仅仅是理论分析,更是一份可供验证、对比和直接使用的性能优化方案指南。

IT 2016-02-06 11:27:50 / 累计浏览 1,590

Swift 的sizeof 和 sizeofValue

这篇讲的是从 C 过渡到 Swift 的开发者,在处理内存尺寸计算时需要注意的关键差异。文章从 C 语言中无处不在的 `sizeof` 运算符切入,指出它在 Swift 中被封装成了两个独立的方法:只能接受类型的 `sizeof` 和接受具体值的 `sizeofValue`。 最关键的区别在于 `sizeofValue` 的行为。它返回的并非像 C 那样的数组内容总大小,而是这个值本身(在 Swift 中往往是一个引用)的内存尺寸。作者用一个 `[CChar]` 数组的例子做了清晰对比:在 C 中 `sizeof(bytes)` 得到 3,而在 Swift 中 `sizeofValue(bytes)` 在 64 位系统下得到的是 8,这实际上是数组引用的长度。 文章接着指出了由此带来的实践影响:若要在 Swift 中像生成 `NSData` 时计算缓冲区大小,不能再直接使用 `sizeofValue`,而需要结合 `sizeof(CChar)` 和 `count` 属性进行手动计算。最后,文章通过一个关于枚举类型的练习题,引导读者深入思考 `sizeof` 与 `sizeofValue` 配合原始值时的不同表现,巩固对这一新模型的理解。

IT 2016-01-27 22:41:02 / 累计浏览 1,529

Swift隐式解包 Optional

这篇讲的是 Swift 中 `ImplicitlyUnwrappedOptional`(隐式解包 Optional)的本质与使用权衡。 它指出,隐式解包 Optional(用 `!` 声明)在本质上与普通 Optional 完全相同,核心区别在于编译器会为其自动插入解包操作,允许你像访问非 Optional 类型一样直接访问其成员。这在代码书写上带来了便利,例如 `maybeObject.foo()` 无需手动加 `!`。 文章追溯了其历史成因:主要是为了在 Swift 早期,更方便地兼容和调用那些从 Objective-C 转换而来、且可能返回 `nil` 的 Cocoa API,作为一种“妥协方案”。不过,随着 Objective-C 引入 `nonnull`/`nullable` 等修饰符以及 Apple 对 Swift API 的不断完善,这种危险特性已大幅减少使用。 如今,最常见的场景仅限于 Interface Builder 连接的 `IBOutlet`。作者建议,在代码的其他部分应谨慎使用隐式解包 Optional,因为它并不意味着“变量一定有值”,而只是一种可能引发崩溃的便捷写法。对于绝大多数情况,使用 `if let` 进行 Optional Binding 是更安全的选择。

IT 2016-01-27 22:33:27 / 累计浏览 1,930

Swift的多重 Optional

这篇技术博客聚焦于Swift语言中一个容易引起混淆的细节——多重Optional。作者从Optional本质是一个枚举类型(`enum Optional`)出发,指出它能够嵌套装入另一个Optional自身,形成了“盒中盒”的结构。 文章的核心对比在于两种对`String??`类型赋值nil的方式。一种是通过已有的Optional变量赋值(`var anotherNil: String?? = aNil`),另一种是直接对字面量nil赋值(`var literalNil: String?? = nil`)。虽然两者打印调试信息时都显示`nil`,但它们的内部结构不同:前者是“盒子中装着一个空盒子”,后者是“盒子中直接是空”。这种差异在使用`if let`进行解包时会显现出来——前者能成功进入代码块,后者则不能。 为解决调试时的困惑,作者推荐使用LLDB的`fr v -R`命令来查看变量的未加工内存布局,从而清晰分辨出`Some(None)`与`None`的区别。文章通过生动的比喻和具体的代码示例,揭示了这一语法陷阱的根源,为开发者在处理复杂Optional解包和调试时提供了明确的指引。

IT 2015-12-13 21:43:13 / 累计浏览 4,577

APP的推送是咋回事

你有没有好奇过,为什么明明关闭了淘宝或新闻APP,它们第二天却又能出现在通知栏里?这篇科普文从这个常见现象入手,拆解了APP推送背后的“小动作”。 文章解释,传统APP采用“拉”模式:只有你打开应用,它才去服务器请求新内容。而推送系统则相反,是服务器主动“推”消息给手机,甚至能唤醒已关闭的APP。要实现这一点,核心是建立并维持一条与服务器的“长连接通道”。通过定期发送“心跳”包保持通道活跃,服务器便能随时下发新消息。 文章进一步对比了“轮询”(反复请求)与“长连接”两种方案的利弊,并深入Android与iOS的不同实现。iOS通过APNs建立了统一的系统级通道,解决了多个APP各自为政的问题。而在国内Android生态中,由于缺乏GCM,各APP只能自建长连接,并与手机管家类应用的“后台清理”机制持续对抗,衍生出了自启、互唤等生存策略。 整篇文章用打电话、心跳这些生动的比喻,把推送技术从原理到现实中的博弈讲得透彻又有趣,帮你真正看懂手机里那些“不请自来”的通知是怎么来的。

IT 2015-11-08 22:12:13 / 累计浏览 2,115

自己动手使用 Swift 打造全功能 JSON 解析、生成库

这篇讲的是作者如何从零开始,动手实现一个兼容 SwiftyJSON 核心 API 的纯 Swift JSON 库。 作者最初的动机,是源于在实际项目中使用 SwiftyJSON 时遇到过非合法长字符串导致崩溃的问题,并对实现递归取值(如 `["key"]["key1"]`)的复杂性感到好奇。于是,在一个中秋节,他决定自己动手“复刻”一个,并命名为 JSONNeverDie(永不崩溃)。 文章的核心,是清晰地拆解了整个实现思路。作者设计了两个值类型(struct):`JSONND` 作为入口负责从 `NSData` 等源解析数据;`JSONNDElement` 则专注于递归取值和类型转换。通过重载下标操作符,自然地实现了链式取值。随后,文章详细展示了如何为 `Int`、`String`、`Array` 等常见 JSON 类型实现从 `AnyObject` 到目标类型的“两级”转换,以及如何将对象序列化回格式化的 JSON 字符串。 作者不仅分享了代码,更传递了一种学习方法:通过亲自实现熟悉的工具(造轮子),能深入理解其设计精髓。最终完成的 JSONNeverDie 库,既是一个功能完备的轻量级替代品,也是这个探索过程的结晶。

IT 2015-04-26 22:45:47 / 累计浏览 2,659

iOS界面响应式布局方式对比

这篇技术文章探讨了iOS开发中界面响应式布局方案的演变与对比。作者指出,早期iPhone屏幕单一,开发者普遍使用绝对定位,无需考虑动态布局问题。但随着iPad和多分辨率iPhone出现,苹果推出了Auto Layout方案。 文章重点对比了Auto Layout及其社区改进(如Masonry)与新兴框架CocoaUI的不同设计哲学。Auto Layout本质是相对布局,但官方实现代码冗长、可读性差;Masonry等库虽用更“人话”的语法简化了代码,但仍未脱离相对布局需要依赖相邻控件关系的固有缺陷。 相比之下,CocoaUI借鉴了Web的流式布局思想,主张每个控件自主完成自身布局,无需关心其他控件。文章通过代码示例直观展示,仅需一行代码即可实现Auto Layout中数十行的内边距设置。此外,CocoaUI还支持从HTML/XML文件直接加载界面并预览,进一步提升了开发效率。作者最终推荐开发者尝试CocoaUI,以更简洁直观的方式解决动态布局难题。

IT 2015-03-26 13:32:57 / 累计浏览 2,191

流式布局的原理和代码实现

这篇文章深入解析了流式布局的核心原理与代码实现,适合GUI开发者和前端工程师阅读。作者从最简单的布局模型出发,即控件靠左、靠右或堆叠排列,提出使用两个栈(Stack)数据结构——一个管理靠左控件的位置,另一个管理靠右控件——来高效实现流式布局。伪代码清晰展示了布局管理器的工作流程:当放置新控件时,先检查当前空间是否足够;若不够,则根据浮动方向从对应栈中弹出更高位置的控件来释放空间,确保布局不重叠。 文章重点讨论了两个实现关键:一是控件变化时的级联重布局,从子节点一直传递到根节点,这虽然简单但性能开销

IT 2014-12-29 00:10:12 / 累计浏览 1,974

ios webview 相关

这篇讲的是开发者在iOS原生开发中,通过Objective-C操作WebView加载页面时遇到的两个典型“坑”及其排查过程。 第一个问题是关于携带Cookie的WebView加载。当需要传递带有HTTPOnly标记的登录Cookie时,发现NSHTTPCookie本身并不支持设置这个标记。作者的解决方案是绕开API限制,手动在请求头中拼接Set-Cookie字段,并详细演示了如何在加载前清理旧Cookie、在加载后构建并存储带有httponly标记的Cookie对象,确保了安全性和功能同时生效。 第二个问题涉及URL的细微变化。当页面内的JavaScript行为导致URL从“index.php”变为“index.php#”时,WebView的回调机制出现了异常:只会触发`shouldStartLoadWithRequest`,而不会触发`webViewDidFinishLoad`。这意味着如果开发者在此回调中管理“加载中”提示框,该弹窗可能无法自动隐藏,导致用户体验中断。文章指出了这个容易被忽略的加载状态管理时机问题。 文章最后坦言可能有更好的解决方案,并鼓励读者交流分享,体现了在复杂移动端环境中,对WebView这类“水很深”的组件进行细致调试与经验积累的重要性。

IT 2014-12-02 23:37:05 / 累计浏览 4,877

iOS push服务

这篇文章详细拆解了iOS推送服务的完整工作流程。作者从Provider、APNS和iPhone的三阶段交互模型入手,清晰阐述了Push通知如何从应用服务器最终抵达用户设备。 内容涵盖了从原理到实践的关键环节:包括如何将苹果的SSL证书与私钥文件,通过OpenSSL命令转换为适用于Java、PHP等服务端环境的PEM或P12格式;客户端注册推送、获取DeviceToken并处理通知的Objective-C代码示例;以及JSON格式Notification Payload的构成,明确了alert、badge、sound等字段的用法与字节限制。 文章还特别区分了开发与发布证书的用途,并附上了多种语言服务端实现的参考链接,最后简要提及了本地通知的创建方法,为开发者提供了一套从配置到实现的完整参考。

IT 2014-12-02 23:35:57 / 累计浏览 3,732

iOS设备唯一标识获取策略

这篇讲的是iOS开发中如何可靠地获取设备唯一标识。作者从苹果在iOS 7中开始屏蔽MAC地址(返回固定值02:00:00:00:00:00)这一背景出发,系统梳理了开发者曾用过的和现行的各种方案。 文章对比了UDID(已被苹果禁用)、UUID(会随App卸载而改变)、OPEN UDID(依赖其他应用存在)、以及苹果官方推荐的广告标示符IDFA(可被用户重置)和Vendor标示符IDFV(在特定条件下保持不变)等多种标识符。作者详细分析了每种方法的原理、优缺点及适用场景,例如IDFA适合广告追踪,IDFV适合同一开发商下的应用互联。 核心结论是,没有完美的单一方案。文章最终指出,一种相对稳健的做法是在应用首次启动时生成一个UUID,然后将其保存在iOS的Keychain中。Keychain数据不受App卸载影响,从而可以在应用重装后依然识别出是同一设备。这对于需要持久化用户身份(如免重复登录)的场景,提供了一个可行的折衷思路。

IT 2013-10-08 12:36:24 / 累计浏览 3,718

在iOS中使用icon font

作者在开发阿里数据iOS客户端时,面临着所有图标都采用传统背景图片方案带来的困境——为兼容普通屏与Retina屏,每个图标都需提供两种尺寸,大大增加了设计师的工作量。由此出发,文章探索了能否将Web上已广泛应用的icon font技术引入iOS开发,并给出了肯定的答案。 文章首先以KaushanScript字体为例,详细拆解了在iOS项目中添加并使用自定义字体的完整四步流程:导入字体文件、在.plist中注册、查找字体集名称、最终调用。掌握此原理后,作者以fontello图标库为例,进一步阐述了使用icon font的特殊之处:核心在于通过FontLab Studio等工具找到图标对应的unicode码(如“\U0000E802”),然后在代码中直接以该unicode字符串进行渲染。 这套方案不仅能轻松使用海量开源图标,更关键的是图标作为字体,其颜色、大小均可通过代码灵活控制,有效解决了多分辨率适配与设计成本问题。文章最后还提供了多个实用的图标字体库资源和示例代码,便于读者直接上手实践。

IT 2012-09-16 23:30:33 / 累计浏览 1,829

主流移动设备的屏幕参数

这篇讲的是,作者在iPhone 5发布之际,出于好奇去追溯历代iPhone的屏幕参数,却在维基百科上意外发现了一个堪称“宝藏”的页面——主流移动设备的屏幕参数大全。这个发现给他的惊喜,甚至超过了新手机本身。 这份资料的价值在于其系统性和全面性。它并非只罗列某一款设备,而是横向汇总了市面上主流移动设备的屏幕核心数据,包括屏幕分辨率、宽高比、PPI(像素密度)、屏幕比例以及CSS像素比等关键指标。这些看似枯燥的数字,实际上是进行移动端网页开发,尤其是响应式设计时,至关重要的参考依据。 作者将这个维基百科页面直接分享了出来,省去了开发者们四处搜集和整理碎片信息的麻烦。如果你正面临不同屏幕尺寸的适配问题,或者想对当前移动设备的显示规格有个整体概念,这份现成的参数列表无疑提供了一条高效的捷径。

IT 2012-03-11 22:40:22 / 累计浏览 3,402

iPhone中png图片格式处理

这篇讲的是如何还原iPhone应用中被“优化”过的png图片。我们知道,苹果在打包App时会对png资源进行特殊压缩以减小体积,导致这些图片无法用常规看图软件直接打开。作者从这个实际问题出发,找到了基于Xcode命令行工具`pngcrush`的解决方案。 核心方法非常直接:通过添加`-revert-iphone-optimizations`参数,就可以将处理过的png反向还原成标准格式。为了克服命令行过长的问题,作者还分享了在终端配置alias的技巧,让操作变得更顺手。文章更进一步,提供了一个简单的shell脚本,能够一键批量转换整个文件夹内的所有png图片,这对于需要处理大量素材的开发者来说相当实用。 整个方案不依赖任何第三方图形工具,完全基于系统自带的环境完成。对于偶尔需要检查或提取iOS应用资源,或者在分析竞品UI时遇到图片无法查看的情况,这个方法提供了一个清晰、可复现的路径。