轩辕十四

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

Objective-C 语言的起源


Objective-C 与 C++,Java 等面向对象的语言类似,不过在很多地方还是有所差别。Objective-C 使用“消息结构”(messaging structure)而非“函数调用”(function calling)。

消息结构的语言与函数调用的语言关键区别在于:

  • 使用消息结构的语言,其运行时所应执行的代码由运行环境决定,也就是说,在运行时才会检查对象类型。接收一条消息之后,究竟应执行何种代码,由运行期环境而非编译器来决定;
  • 使用函数调用的语言,运行时所执行的代码由编译器决定;

要点:

  • Objective-C 为 C 语言添加了面向对象特性,是其超集。Objective-C 使用动态绑定的消息结构,也就是说,在运行时才会检查对象类型。接收一条消息之后,究竟应执行何种代码,由运行期环境而非编译器来决定。
  • 理解 C 语言的核心概念有助于写好 Objective-C 程序。尤其要掌握内存模型与指针。

在类的头文件中尽量少引入其他头文件


在类的头文件中(.h)我们一般不需要知道引入的某个类的全部细节,这时候,我们可以用 @class 关键字去告诉编译器,知道有一个类名为 xxx 的类就好,不需要关注细节。

这叫做“向前声明”(forward declaring)该类。在实现文件(.m)中我们使用该类时就需要知道其所有细节,这时我们需要用 #import 关键字去导入 xxx 类的头文件。

将引入头文件的时机尽量延后,只有确有需要时才引入,这样就能减少类的使用者所需引入头文件的数量。这样能够一定程度上的减少编译的时间

阅读全文 »

我们都知道 Objective-C 是一门动态的语言,有的时候我们会使用 Runtime 处理一些在 Objective-C 上面无法实现或者很难实现的功能。例如:在扩展中添加属性;动态的获取属性的名称,方法名等。那么究竟什么是 Runtime

什么是 Runtime

Runtime 简称运行时。Objective-C 就是运行时机制,也就是在程序运行时候的一些机制,其中最主要的是消息机制。对于我们熟悉的C语言,函数的调用在编译的时候会决定调用哪个函数。但对于 Objective-C 的函数,属于动态调用过程,在编译的时候并不能决定真正调用哪个函数,只有在真正运行的时候才会根据函数的名称找到对应的函数来调用。

也就有了下面这两点结论:

  1. 在编译阶段,Objective-C 可以调用任何函数,即使这个函数并未实现,只要声明过就不会报错。
  2. 在编译阶段,C语言调用未实现的函数就会报错。
阅读全文 »

无并发,不编程。并发在开发中是非常重要的一个技术,运用并发技术,可以写出高性能的程序,并发能够有效地利用多核心 CPU 的优势来提高数据处理的速度。作为一个码农,学好并发是十分有必要的。iOS有四种多线程编程的技术,分别是:NSThread,Cocoa NSOperation,GCD(全称:Grand Central Dispatch), pthread。今天我们就重点讲一讲 GCD 中的并发,锁和线程同步。

GCD 中的并发


GCD 队列默认就是串行的(serial),在 GCD 中创建并发队列是如下所示:

1
let concurrent = DispatchQueue(label: "com.demo.concurrentQueue", attributes: .concurrent)

DispatchQueueattributes 参数还有一个取值:initiallyInactive,这是可以手动管理队列执行时间的参数。
当一个队列声明为 initiallyInactive 时,这个队列不会自动开始执行,必须要调用 activate() 方法。对应的还有 suspend()resume()

  • activate():开始执行队列
  • suspend():挂起队列
  • resume():继续执行队列

关于 initiallyInactive 到这里为止,我们继续说说并发队列。

阅读全文 »

但是,我仍然不明白,KVC 和属性访问(property accessor)方法有什么区别?


KVC 是调用属性访问器方法或以其他方式访问属性的一种方法。

“以其他方式访问”是什么意思?

对于 KVC 而言,没有访问器方法的实例变量会被视为非正式属性。
如果没有找到匹配的访问器对,它将直接获取或设置实例变量的值。
(是的,在现代代码中这是不值得使用的,总是为任何你想访问的任何东西声明一个 @property,反之,不要使用 KVC 来访问任何不属于公共属性的东西。)

属性访问器方法是 KVC 在其存在的情况下会调用的方法(KVC 和每个理智的程序员都倾向于直接 ivar 访问)。访问者可以获取或设置实例变量,如合成访问者所做的那样,或者访问某些其他存储。

访问器是实现,属性是接口,KVC 是使用它们的一种方式。

阅读全文 »

我在使用 Playground 的时候,喜欢将自定运行(Automatically Run)修改为手动运行(Manually Run),因为自动运行有时会导致我的 Xcode 卡住,体验非常不好。但是 Playground 并没有相应的快捷键去手动执行 Playground,这又导致手动运行的时候操作繁琐,每次都要靠鼠标去点,作为一个程序员怎么能忍受这种没有效率的操作 😂。接下来我们为手动执行 Playground 添加一个快捷键。

打开系统偏好设置中的快捷键设置


系统偏好设置 -> 键盘 -> 快捷键

选中最后一个,应用快捷键

阅读全文 »

我想要创建一个 Observable

  • 产生特定的一个元素: just
    • 经过一段延时: timer
  • 从一个序列拉取元素: from
  • 重复的产生某一个元素: repeatElement
  • 存在自定义逻辑: create
  • 每次订阅时产生: deferred
  • 每隔一段时间,发出一个元素: interval
    • 在一段延时后: timer
  • 一个空序列,只有一个完成事件: empty
  • 一个任何事件都没有产生的序列: never
阅读全文 »

just 、 from 和 of


justfrom 都能够将元素转化为 Observable 但是他们有本质的区别:

just

创建 Observable 发出唯一的一个元素just 操作符将某一个元素转换为 Observable

示例:

1
2
3
4
5
6
7
let oJust = Observable.just([1, 2, 3, 4, 5])
oJust.subscribe(onNext: {
print($0)
})
.dispose()

// [1, 2, 3, 4, 5]
阅读全文 »

Error Handling - 错误处理


一旦序列里面产出了一个 error 事件,整个序列将被终止。RxSwift 主要有两种错误处理机制:

  • retry - 重试
  • catch - 恢复

retryWhen

如果请求 JSON 失败,我们需要等待5秒后进行重试操作,重试4次如果全部失败则抛出错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 请求 JSON 失败时,等待 5 秒后重试,
// 重试 4 次后仍然失败,就将错误抛出

let maxRetryCount = 4 // 最多重试 4 次
let retryDelay: Double = 5 // 重试延时 5 秒

rxJson
.retryWhen { (rxError: Observable<Error>) -> Observable<Int> in
return rxError.flatMapWithIndex { (error, index) -> Observable<Int> in
guard index < maxRetryCount else {
return Observable.error(error)
}
return Observable<Int>.timer(retryDelay, scheduler: MainScheduler.instance)
}
}
.subscribe(...)
.disposed(by: disposeBag)
阅读全文 »

Observer - 观察者


AnyObserver


AnyObserver 可以用来描叙任意一种观察者。

例如:

打印网络请求结果:

1
2
3
4
5
6
7
URLSession.shared.rx.data(request: URLRequest(url: url))
.subscribe(onNext: { data in
print("Data Task Success with count: \(data.count)")
}, onError: { error in
print("Data Task Error: \(error)")
})
.disposed(by: disposeBag)
阅读全文 »

Observable - 可被监听的序列


所有的事物都是序列

Observable 可以用于描述元素异步产生的序列。这样我们生活中许多事物都可以通过它来表示。

如何创建序列

创建序列最直接的方法就是调用 Observable.create,然后在构建函数里面描述元素的产生过程。 observer.onNext(0) 就代表产生了一个元素,他的值是 0。后面又产生了 9 个元素分别是 1, 2, ... 8, 9 。最后,用 observer.onCompleted() 表示元素已经全部产生,没有更多元素了。

阅读全文 »
0%