轩辕十四

探索科技与创新的个人博客

实现一个名叫 Multiset 的集合数据结构,要具有如下的方法

  1. count(for:) 返回相应数据的存储个数;
  2. add(_:) 添加数据;
  3. 删除数据remove(_:)

举例:

1
2
3
4
5
6
7
8
m = Multiset()
m.add("cat")
m.add("dog")
m.add("cat")

m.count(for: "cat") -> 2
m.remove("cat")
m.count(for: "cat") -> 1
阅读全文 »

前阵子忙疯了,最近得空,来更新一下自己的博客 - 记一次 macOS 安装/配置 Jenkins 的过程,方便以后使用。

由于 macOS 新系统 Mojave 字体实在让人看着眼疼,昨天重新装回了 macOS High Sierra,并且机智的用 ThinBackup 备份了自己的项目配置,避免麻烦,配置上面的东西还是挺多的。

阅读全文 »

我升级到 macOS Sierra(以及后来的 Mojave),我试着在终端运行 git 命令,但是它一直显示如下的错误:

1
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun

我该如何解决?

阅读全文 »

最近,Google 开源了其 TCP BBR 拥塞控制算法,并提交到了 Linux 内核,从 4.9 开始,Linux 内核已经用上了该算法。根据以往的传统,Google 总是先在自家的生产环境上线运用后,才会将代码开源,此次也不例外。
根据实地测试,在部署了最新版内核并开启了 TCP BBR 的机器上,网速甚至可以提升好几个数量级。
于是我根据目前三大发行版的最新内核,开发了一键安装最新内核并开启 TCP BBR 脚本。

阅读全文 »

今天在做在线预览功能的时候碰到了一个蛋疼的问题,office 格式都可以完美的适配,但是 txt 格式出现了乱码。没办法只能进行一个转码,然后再输出内容。

提取 TXT 文件内容并转码 utf8


1
2
3
4
5
do {
var encoding: String.Encoding = .utf8
let body = try String(contentsOf: url, usedEncoding: &encoding)
return body
} catch {}

这里我们的 body 就是我们获取的内容,默认的我们用了 utf8 编码格式,如果转码错误,说明文件的编码格式为其他格式。

阅读全文 »

跨线程订阅的问题似乎在 RxSwift Slack 上一次又一次的被提到。这个解释起来也是非常的简单所以我觉得放在博客当中是一个好主意,无论你在何时需要,都可以通过连接进行访问,我也不用一次又一次的回复。

可观察序列的订阅(Observable subscriptions)


subscribing(订阅) 和 observing(观察) 方面的术语还有一点混乱,所以让我们先来解决这个问题(不要跳过本章节!)。

让我们看看 observable subscription 的工作原理。我们可以将订阅分成 3 个部分:

阅读全文 »

最近在做的一款 App 测试中出现了一个非常诡异的问题,偶尔的界面卡死,但是又并不是 Crash,没有抛出任何异常,把 App 切到后台然后在点开又恢复了,只不过转场的时候十分诡异,似乎完全没有动画,转场背景还是黑的。

什么原因呢?死循环?不可能;内存泄漏?也不可能?😂;手势冲突?很有可能🧐。无意中我发现了,在 UINavigationController 根视图上进行右滑返回上级页面时,页面就会卡死。原因找到了,一定是手势冲突。

问题原因描述


在我的项目中有一个基类 BaseViewController,由于项目中有时候需要隐藏 NavigationBar 所以我使用了 setNavigationBarHidden() 方法,使用这个方法会导致右滑返回上级页面的操作失效。所以我在 BaseViewController 中加入了如下的代码:

1
2
3
4
self.navigationController?.interactivePopGestureRecognizer?.delegate = self

extension BaseViewController: UIGestureRecognizerDelegate {
}

我没有实现任何 UIGestureRecognizerDelegate 的方法,也就是用的都是默认情况。右滑时,具体的操作是将导航栏堆栈最顶部的 Controller 进行 pop 操作,但是当栈顶没有 Controller 时,也就是 ControllerrootViewController 时,这时候去开启右滑就会出问题了。导致页面完全卡死。

阅读全文 »

更新说明:本教程已由 Nikolas Burk 更新为 Xcode 9,iOS 11 和 Swift 4。最初的教程由 Chris Wagner 编写。

这篇教程向你展示了如何在 Swift 平台上使用流行的数据库 SQLite。在软件开发的领域,你需要很长时间才能保存应用数据。在很多情况下,这是以数据结构形式出现的。但是,如何有效的存储它 – 什么是有效的存储?

幸运的是,一些伟大的思想家已经开发出用于在数据库中存储结构化数据和编写语言功能以访问数据的解决方案。SQLite 默认在 iOS 中是可用的。实际上,如果你以前使用过 Core Data,那么你实际上已经使用过 SQLite,因为 Core Data 只是 SQLite 上的一个层封装,它提供了更方便的API。

通过这篇教程,你将学习到如何执行以下数据库的操作:

  • 创建和连接一个数据库
  • 创建一个表
  • 插入一行
  • 更新一行
  • 删除一行
  • 查询数据库
  • 处理 SQLite 错误

在学习如何执行这些基本操作之后,你将看到如何以类似 Swift 的方式将它们包装起来。这将允许你为应用程序编写抽象 API,以便你(大多数)可以避免去直接使用 SQLite 的 C API 的痛苦!:]

最后,我将简要介绍一下流行的开源 Swift 包装器 SQLite.swift,以便你能大致的了解一下底层框架是如何工作的。

注意:数据库,甚至只是 SQLite 本身,都是一个非常大的主题,因此它们大多超出了本教程的范围。本教程假设你对关系数据库意识形态有基本的了解,并且你主要在这里学习如何在 Swift 下使用 SQLite。

阅读全文 »

之前我们说过了运用面向协议的思想为控件添加 action 今天我们再来写一个基于 Storyboard 的初始化方法。在我的项目中,我没有将所有的 controller 都放在一个 Storyboard 文件中,原因有两个:

  • Controller 很多的时候不方便查找对应的 Storyboard
  • 打开 Storyboard 会非常卡。

所以我将 Controller 拆分成一个个的 Storyboard 文件。在对应的类中,我需要在每个类都写上一个初始化方法:

1
2
3
4
static func instantiate() -> HomeViewController {
return UIStoryboard(name: .home)
.instantiateViewControllerWithClass(type: HomeViewController.self)
}
阅读全文 »

在项目中,往往有这样的要求,用 API 进行登录之后在某个 WKWebView 的页面需要用 cookie 去验证身份(虽然我更喜欢用 accesstoken 去验证🙃)。WKWebView 是苹果官方建议的控件来替代老旧的 UIWebView。但是 WKWebViewcookie 无法共享 NSHTTPCookieStorage,所以这时候就需要我们自己去管理 cookie。(iOS 11 上新增了 WKHTTPCookieStore 来管理)

首先我们先解析获取到的 cookie

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/// 解析 cookie
private func analysisCookie(response: HTTPURLResponse) {

if let fields = response.allHeaderFields as? [String: String],
let url = response.url
{
let cookies = HTTPCookie.cookies(withResponseHeaderFields: fields,
for: url)
let storage = HTTPCookieStorage.shared
for cookie in cookies {
/// 将 cookie 存入本地
storage.setCookie(cookie)
}
}
}
阅读全文 »
0%