0%

Runtime是什么

Runtime是一个库,这个库使我们可以在程序运行时创建对象、检查对象,修改类和对象的方法。

  • OC是一门动态性比较强的编程语言,允许很多操作推迟到程序运行时再进行;
  • Runtime是一套C语言的API,封装了很多动态性相关的函数;
  • OC的动态性就是由Runtime API来支撑和实现的

基础知识

  1. arm64架构之前,isa就是一个普通的指针,存储着ClassMeta-Class对象的内存地址;
  2. 从arm64架构开始,对isa进行了优化,变成了一个共用体(union)结构,还使用位域来存储更多的信息;
  3. 类对象、元类对象的地址值(二进制)最后三位一定是0,所以16进制的地址值末位总是0或者8;

isa的位域信息:

​ isa共用体的64位数中有33位存储的是类/元类的内存地址信息

阅读全文 »

iOS开发中,H5页面一般都会做客户端适配,比如在header标签中添加viewportmeta标签,设置宽高100%适配或使用device-width适配宽度,在初始化webview时,客户端一般会再做一层适配,添加width=device-width属性:

1
2
3
4
5
6
let jScript = """
var meta = document.createElement('meta');
meta.setAttribute('name', 'viewport');
meta.setAttribute('content', 'width=device-width');
document.getElementsByTagName('head')[0].appendChild(meta);
"""

但是在有输入框的H5页面,调起键盘后仍然会使页面放大、输入框被顶出页面顶部等问题。

阅读全文 »

在开发中,点击事件一般都是使用UIButton来实现。有时候也会出现请用户阅读并同意多个协议的情况,不同的协议有不同的跳转,这时就需要做成超链接的形式。在iOS中简单实现超链接的方式就是使用UITextView

实现步骤:

首先,要给文本添加超链接属性(NSAttributedString.Key.link),可以响应超链接的文本默认为蓝色,有两种添加方式:

  • 方式1:设置该属性的value值为要跳转的超链接地址
  • 方式2:设置该属性的value值为自定义URL Scheme
    阅读全文 »

App中的耗电大户:CPU和I/O操作

如何获取电量

IOKit framework是专门用于跟硬件或内核服务通信的。所以,我们可以通过IOKit framework来获取硬件信息,进而获取到电量消耗信息。

使用:导入IOPowerSources.hIOPSKeys.hIOKit,将batteryMonitoringEnable设置为true,通过代码获取精确到1%的电量信息:

阅读全文 »

在iOS开发中,要加载PDF,一般可以直接使用WKWebview来加载。但是PDF中的电子签章常常显示失败。除了使用第三方库来解决之外,有没有其他解决方案呢?我的解决方案是下载PDF文件后保存到本地,然后使用QLPreviewController加载本地文件。

QLPreviewController简介

QLPreviewController API在iOS中用来预览文件,它支持的文件类型有iWork文档、RTF文档、PDF文件、图片、文本文件和CVS文件等。使用的时候需要遵守并实现QLPreviewControllerDataSourceQLPreviewControllerDelegate两个代理的方法。

阅读全文 »

在iOS中,如果需要使用H5页面,前端经常需要使用userAgent来判断调用页面的客户端类型。

如果我们要设置自定义userAgent,可以直接调用webView.customUserAgent = "your customer userAgent"。但是很多时候,前端需要的是原始userAgent拼接自定义内容,这时候就需要先获取webView的原始userAgent。

在iOS中,要获取WKWebview的原始userAgent,可以使用evaluateJavaScript方法来获取。这个方法是异步的,所以在自定义的WKWebview中,url加载完成可能早于获取到userAgent,从而造成加载H5的页面时,前端获取不到自定义的userAgent。所以需要我们在加载url之前,获取并设置WKWebview的userAgent。

阅读全文 »

使用3DES加密时,遇到后端加解密数据与iOS加解密数据不一致的问题,特此记录下。

后端使用的算法algorithm参数是ecb,iOS端使用kCCOptionECBMode或者kCCOptionPKCS7Padding时,如果加密的原始数据全是数字类型时,可以得到相同的加解密结果。但是,当原始数据包含特殊字符或者字母时就跟后端得到的不一致了,正确的设置是使用(kCCOptionECBMode + kCCOptionPKCS7Padding)

在3DES加密中,key值是24位字符串,一般我们是将原始key值经过md5加密后截取前24位作为3DES加解密的key来使用。

阅读全文 »

iOS11后,如果没有设置UIScrollView.appearance().contentInsetAdjustmentBehavior = .automatic,调用相册后,导航栏会遮挡相册照片。解决方法:

present UIImagePickerController之前设置:

1
2
3
if #available(iOS 11.0, *) {
UIScrollView.appearance().contentInsetAdjustmentBehavior = .automatic
}

dismiss之前设置:

阅读全文 »

当tab的childController都是navigationController,其中两个navigationControllerrootViewController都是需要隐藏导航条的,在这两个controllerviewWillAppear中设置了 navigationController?.setNavigationBarHidden(false, animated: true),但是在切换这两个tab的时候,视图会发生明显的上移动画,这是我们不希望的。

阅读全文 »

bridge在registerHandler时可以获取data,如果前端传过来的data是个json数据,我们却无法直接将data作为json处理。

这是由于JavaScriptBridge对前端传来的data做了处理,data是个对象,而不是json。所以我们需要将data对象转成json再进行处理:

阅读全文 »