Swift
中的整型类型提供了两个属性分别获取其大端字节序表示(bigEndian
)和小端字节序表示(littleEndian
)。如果想在Swift判断当前平台的字节序是大端还是小端,可以简单的使用如下语句:
let isLittleEndian = 1 == 1.littleEndian
Swift
中的String
本身不是一个集合,不过它提供了一些属性来将其内容表示为集合。不同的属性可以将字符串呈现为不同的可视化及数据表示的视图,主要有4种类型:
Character View
(characters
属性,类型为String.CharacterView
):扩展字符集群的集合,类似于自然语言字符。主要是以Unicode
字符来表示;Unicode Scalar View
(unicode Scalars
,类型为String.UnicodeScalarView
):Unicode
标题值的集合,即以21-bit
作为Unicode
的基本单元的值;UTF-16 View
(utf16
属性,类型为String.UTF16View
):UTF-16
字符的集合,即以16-bit
作为Unicode
的基本单元的值;UTF-8 View
(utf8
属性,类型为String.UTF8View
):UTF-8
字符的集合,即以8-bit
作为Unicode
的基本单元的值;如果Swift
要和C API
交互,则String
以这种格式传递给C函数;
官方文档给了一个实例,如图1所示,可以看到这几种表示方式的区别。
let cafe = "Cafe\u{301} du 🌍"
print(cafe.unicodeScalars.count)
// Prints "10"
print(Array(cafe.unicodeScalars))
// Prints "["C", "a", "f", "e", "\u{0301}", " ", "d", "u", " ", "\u{0001F30D}"]"
print(cafe.unicodeScalars.map { $0.value })
// Prints "[67, 97, 102, 101, 769, 32, 100, 117, 32, 127757]"
print(cafe.utf16.count)
// Prints "11"
print(Array(cafe.utf16))
// Prints "[67, 97, 102, 101, 769, 32, 100, 117, 32, 55356, 57101]"
print(cafe.utf8.count)
// Prints "14"
print(Array(cafe.utf8))
// Prints "[67, 97, 102, 101, 204, 129, 32, 100, 117, 32, 240, 159, 140, 141]"
参考
从iOS 10.3
(目前还是beta版本)开始,保存在keychain
中的App相关的数据,会随着应用的删除而被清除,重新安装App后将无法再从keychain
中获取应用相关的数据。而10.3之前删除App并不会清理keychain
中的对应数据。
如果希望App在重新安装后,仍然可以获取到之前的一些数据,则依赖于keychain
的方案将变得不可靠。
不过,如果数据是在多个App间共享,则只有当所有相关的App都被删除后,才会删除keychain
中的这些共享数据。
至于具体原由,可以参考iOS 10.3 Beta 2 autodeletes keychain items after application uninstall?。
This is an intentional change in iOS 10.3 to protect user privacy. Information that can identify a user should not be left on the device after the app that created it has been removed.
It has never been a part of the API contract that keychain items created by an app would survive when the app is removed. This has always been an implementation detail.
If a keychain item is shared with other apps, it won't be deleted until those other apps have been deleted as well.
There is documentation in the works about this change that should address questions raised in this thread.
UIWebView
可以直接打开PDF文件,代码很简单,如下所示:
@IBOutlet weak var webView: UIWebView!
override func viewDidLoad() {
super.viewDidLoad()
let filename = Bundle.main.path(forResource: "test", ofType: "pdf")
let url = URL(fileURLWithPath: filename!)
let request = URLRequest(url: url)
self.webView.scalesPageToFit = true
self.webView.loadRequest(request)
}
效果如下图所示:
加载的PDF文件是放置在一个UIWebPDFView
视图中,UIWebPDFView
应该是一个私有类,可以在 UIWebPDFView.h查看其声明。
iOS模拟器的Debug
菜单中提供了几个菜单项来检测影响帧率的一些因素:
Color Blended Layers
: 高亮显示有混合操作的区域;Color Copied Images
: 高亮显示被拷贝的图片。拷贝图片意味着Core Animation
需要拷贝一份图片并发送给render server
,这对内存和CPU的使用都是昂贵的;Color Misaligned Images
: 高亮显示缩放或拉伸过的图片,或者没有正确对齐对到像素边界的图片;Color Offscreen-Rendered
: 高亮显示离屏渲染的层对象。
当然这几个选项在Instrument
的Core Animation
工具中也可以找到。
参考
iOS Core Animation Advanced Techniques
OmniGraffle
无法绘制Swift
的类图,只能再找个替代工具:swift auto diagram
。这是一个ruby写的开源库。
下载源码后,可以在工具所在目录下执行命令:
ruby generateClassDiagram.rb ~/workspace/my-swift-project
然后会生成一个静态html页面,如图所示。
可以看到其以不同颜色标出了protocol
, class
, struct
, extension
等类型及它们之间的关系。在这个页面里面可以自由地拖动类型框。嗯,不过,谈不上美观啊~~~
参考
Core Animation
中CPU的操作在动画开始前执行,所以通常不会影响到动画的帧率,但是会影响到动画的开始。以下一些操作会延迟动画的开始时间:
- 布局计算:这可以理解,视图越复杂,需要的计算量越大。特别注意
auto layout
是一种CPU密集型操作,比传统的autoresizing
更耗CPU; - 延迟加载视图机制:这个机制带有两面性,优点是优化内存使用和启动时间;缺点的涉及到IO操作;
Core Graphics
绘制:自定义的-drawRect:
或-drawLayer:inContext:
会引入显著的性能开销;因为Core Animation
会在内存中创建一个与视图等大小的backing image
用来绘制,然后再通过IPC
将这个图片数据发送给render server
;- 图片解压。
参考
iOS Core Animation Advanced Techniques