IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

移动开发

共 365 篇文章

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

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,560

自己动手打造基于 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,306

自己动手打造基于 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 / 累计浏览 2,051

自己动手打造基于 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,676

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:25:11 / 累计浏览 1,649

YYCache 设计思路

这篇讲的是作者从实际需求出发,设计高性能iOS缓存库YYCache的思考过程。他对比了NSCache、TMMemoryCache、PINMemoryCache等主流内存缓存实现,发现它们在性能或功能上各有不足,于是YYMemoryCache采用了OSSpinLock保证线程安全,并实现了LRU淘汰算法,在基准测试中性能表现突出。 针对磁盘缓存,文章分析了基于文件、mmap和SQLite三种技术路径的优劣。作者指出SQLite在存储小数据时性能更优,且便于实现元数据管理和淘汰策略,因此YYDiskCache采用了SQLite结合文件存储的混合方案,在实测中兼顾了性能与功能。 最后,作者还对比了Realm与SQLite的性能差异,并提到Realm会向外部IP发送数据,建议开发者谨慎使用。整篇文章从技术选型到性能评测,为iOS开发者选择和构建缓存方案提供了详实的参考。

本机暂存
IT 2016-02-07 14:23:53 / 累计浏览 2,610

移动端图片格式调研

这篇技术调研从移动端流量与视觉体验的双重痛点出发,系统梳理了从老牌JPEG、PNG、GIF到新兴WebP、APNG、BPG的多种图片格式。作者不仅对比了它们在压缩率、透明通道、动画支持等方面的核心差异,更深入到Android与iOS底层编解码架构(如Skia、ImageIO)和具体开源库(如libjpeg-turbo、MozJPEG)的性能剖析。 文章的亮点在于其扎实的实测数据。通过在iPhone 6上对典型图形与照片素材进行编解码测试,直观呈现了不同格式在文件体积、处理速度上的权衡。例如,JPEG在quality 0.9时达到较好的质量与效率平衡;PNG处理照片类图片时体积和速度明显逊色;而WebP凭借其全能特性和广泛的应用,已成为移动端优化的重要选择。 对于关注移动端性能优化的开发者来说,这篇文章提供了清晰的选择指南:WebP是当前均衡且普及的解决方案,APNG在动图上优于GIF,而高压缩比的BPG则代表了未来方向,尽管其仍受版权与计算成本制约。

本机暂存
IT 2016-02-07 14:10:46 / 累计浏览 3,703

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,653

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,588

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,992

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:56:38 / 累计浏览 3,746

网页与原生App如何交互

这篇讲的是网页与原生App之间那道“隐形的墙”是如何被打通的。作者从日常场景切入——比如用App时点击登录,瞬间唤起微信授权,无需输入密码——引出了核心问题:这种流畅的交互背后是什么技术在支撑? 文章以Android的Js2Java机制为例,剖析了WebView如何充当“桥梁”,让运行在网页端的JavaScript与原生App的Java代码能够互相调用。作者特别点出,虽然Java和JavaScript名字相似,但本质迥异,而WebView正是连接这两个世界的组件。通过这个桥梁,网页可以调用原生系统的电话、支付等能力,极大地丰富了H5页面的功能。 文章也指出了这是一把“双刃剑”:原生App开放的能力越多,网页的体验就越接近原生,但恶意页面也可能利用这些能力。因此,能力的开放需要精细的权限控制,就像微信那样,前端必须申请接口权限才能使用支付等功能。 最终,这种交互技术让开发者能取长补短:用网页的灵活性实现快速更新和运营,用原生组件提供流畅的核心体验(如支付),从而构建出体验更优的混合型应用。

本机暂存
IT 2015-12-13 21:43:13 / 累计浏览 4,687

APP的推送是咋回事

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

本机暂存
IT 2015-11-08 22:32:55 / 累计浏览 2,353

QQ浏览器X5内核问题汇总

这篇整理自X5团队内部资料的清单,系统梳理了微信、QQ浏览器中使用的X5内核(基于Android 4.2 WebKit)常见的41个开发者问题与解决方案。文章以问答形式展开,覆盖了从布局渲染、脚本性能到多媒体播放、网络定位等广泛场景。 例如,它明确了为何使用iScroll.js局部滚动会卡顿(建议改用CSS overflow属性),解释了-webkit-filter和WebGL在当时的兼容性限制,并给出了定位失败时如何检查JS中timeout参数设置的排查路径。对于Canvas内存限制、Cookie的4KB截断、点击事件300ms延迟等底层机制,也提供了清晰的原理说明和应对建议。 文章最后透露,X5内核团队已启动基于Chromium的新版本预研,以提升标准支持和性能。这份详尽的“避坑指南”,对于至今仍在处理Android WebView碎片化兼容问题的前端与移动端开发者,依然具有直接的参考价值。

本机暂存
IT 2015-11-08 22:12:13 / 累计浏览 2,200

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

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

本机暂存
IT 2015-10-04 23:08:18 / 累计浏览 1,316

Objective-C 运行时的黑魔法之Swizzle

这篇讲的是Objective-C运行时里一项既强大又颇具风险的特性:Swizzle(方法交换)。作者从一个实际需求切入——如何在不改动项目原有代码结构的前提下,为应用中成百上千个UIButton的点击事件统一添加统计逻辑。 文章清晰地揭示了Swizzle的原理:Objective-C在调用方法时,依赖类的“调度表”通过selector查找对应的实现。我们可以在运行时替换这个映射关系,从而“偷天换日”。相比于创建子类或逐处修改代码的传统思路,这无疑是一劳永逸的“黑魔法”。 其核心实现也十分巧妙:通过`method_exchangeImplementations`交换两个selector对应的方法指针。文中以一段Swift示例代码具体展示了如何为UIButton扩展一个计数方法,并与原方法交换实现。最有趣的一点是,在替换方法中调用“自身”时,看似会死循环,实则因为实现已被交换,调用的恰是原始逻辑。 最后,文章还提醒了在Swift中应用Swizzle的注意事项,例如需要利用`initialize`方法触发交换,以及对纯Swift类需要使用`dynamic`修饰以启用动态派发。这既是一次对运行时机制的精彩剖析,也提供了解决特定工程难题的优雅范本。

本机暂存
IT 2015-09-21 14:13:58 / 累计浏览 3,508

iOS安全系列之一:HTTPS

这篇讲的是HTTPS,但不是泛泛而谈。作者从iOS开发者普遍对安全不够重视的现状出发,指出即便是未越狱设备,网络安全依然是不可回避的课题。文章的核心,是厘清HTTPS并非什么新协议,其本质只是在HTTP之下增加了一层SSL/TLS加密。 最硬核的部分在于对SSL/TLS原理的拆解:它通过四次握手交换三个随机数来生成安全的“对话密钥”,并依赖数字证书体系(PKI)进行身份验证。文章用清晰的逻辑讲透了证书的签发与验证流程——接收端如何通过哈希对比和递归验证,最终追溯到操作系统内置的根CA。这解释了“为什么信任链的起点如此重要”。 在实现层面,文章没停留在理论。它具体展示了如何在iOS的NSURLConnection中处理证书验证回调,利用Security Framework的API完成Trust Object的评估。无论是使用系统默认验证,还是为自建证书等高安全场景进行更严格的本地匹配校验,都给出了可落地的代码思路。对于想用AFNetworking简化流程的开发者,也有明确的指引。 从概念辨析到原理图解,再到代码级实践,这篇文章提供了一条清晰的路径,帮助开发者完成从HTTP到HTTPS的安全升级。

本机暂存
IT 2015-09-04 21:45:03 / 累计浏览 4,093

Android安全–检测是否为Android模拟器

这篇讲的是如何在应用层面检测 Android 模拟器环境。作者从应用安全的角度出发,指出在某些场景下(如反欺诈、版权保护)需要区分真机与模拟器,随后提供了一套完整的检测代码实现。 文章的核心思路是综合利用模拟器环境在多个维度留下的特征。代码中演示了几个典型的检查点:首先扫描系统中是否存在已知的 QEMU 虚拟管道文件(如 `/dev/socket/qemud`)或特定的驱动程序标识(如 `goldfish`),这些是 Android 模拟器的标准配置产物;其次,通过读取 `/proc/cpuinfo` 文件检查 CPU 信息,或查询电池状态(如电量始终为满且温度恒定),因为模拟器硬件信息往往显得“完美”且缺乏真实设备的动态变化。 这些检测手段组合起来,能形成一个相对可靠的模拟器判断模型。文章没有停留在理论层面,而是直接给出了可集成的 Java 代码片段,对于需要快速落地检测功能的开发者来说,提供了一个开箱即用的参考方案。

本机暂存
IT 2015-07-17 13:24:44 / 累计浏览 4,593

聊聊移动端跨平台开发的各种技术

这篇讲的是移动端跨平台开发技术的全景分析。作者从React Native的流行切入,将现有的解决方案梳理为四大流派:Web(Hybrid)、代码转换、编译和虚拟机,并深入剖析了各自的原理、优劣与适用场景。 在Web流中,文章跳出了“DOM性能差”的常见误解,指出其根本瓶颈在于早期Android WebView实现粗糙、CSS计算复杂以及上层API限制了底层优化能力。而代码转换流则介绍了如J2ObjC等工具如何在不改变官方技术栈的前提下,实现iOS与Android间高达70%的代码复用(以Google Inbox为例),同时也分析了不同转换方向与目标语言工具的成熟度差异。 作者并未止步于技术罗列,而是结合具体项目(如React-Canvas、HTML-GL)和历史案例,点明了各种路径的现实挑战。例如,Web流在享受CSS丰富表现力的同时,面临着功能滞后于原生API的困境;而代码转换的效率则高度依赖工具链的完成度。整篇文章为开发者在“一次编写,处处运行”的理想与平台差异化的现实之间,提供了清晰的技术路线图与决策参考。

本机暂存
IT 2015-06-04 09:56:04 / 累计浏览 2,478

R u ok--客户端网络优化实践

这篇讲的是客户端网络优化中那些让人头大的真实坑点。作者从和全国用户的大量“亲密接触”中总结出,用户愤怒的根源往往是网络状态切换时,应用没能及时恢复。 比如,你以为IP地址能定位用户,但实际会遇到IP库不准甚至运营商流量劫持;DNS可能不解析或被运营商插入广告;协议和端口也可能被拦截。这些“不可靠”的因素,单纯依赖服务器端策略很难根治。 文章的核心思路是“客户端必须能适应环境”。当网络从差变好时,应用必须迅速反应过来并恢复,而不是卡在旧状态。具体解法包括:不依赖IP而用smartDNS,维护好socket的连接状态机,在WiFi和不同移动网络下设置差异化的连接与发送超时,遇到EPIPE/ECONNRESET等错误时果断重连,以及准备多套协议与端口方案作为后备。 最后作者点出关键:网络可以时好时坏,但用户体验必须能“迅速恢复”。这些基于血泪教训的实战细节,对做移动端和跨平台开发的同学非常实用。

本机暂存