Skip to content

Commit

Permalink
Merge pull request oa414#36 from Hs-Yeah/fix-typo
Browse files Browse the repository at this point in the history
Fix typo,修饰语句以增强可读性,修正翻译错误
  • Loading branch information
oa414 committed Sep 21, 2015
2 parents 7b2d599 + 384a355 commit d84b935
Showing 1 changed file with 13 additions and 13 deletions.
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -631,14 +631,14 @@ designated 初始化方法是提供所有的参数,secondary 初始化方法
#### Designated Initializer
一个类应该又且只有一个 designated 初始化方法,其他的初始化方法应该调用这个 designated 的初始化方法(虽然这个情况有一个例外)
一个类应该有且只有一个 designated 初始化方法,其他的初始化方法应该调用这个 designated 的初始化方法(虽然这个情况有一个例外)
这个分歧没有要求那个初始化函数需要被调用。
在类继承中调用任何 designated 初始化方法都是合法的,而且应该保证 *所有的* designated initializer 在类继承中是是从祖先(通常是 `NSObject`)到你的类向下调用的。
在类继承中调用任何 designated 初始化方法都是合法的,而且应该保证 *所有的* designated initializer 在类继承中是从祖先(通常是 `NSObject`)到你的类向下调用的。
实际上这意味着第一个执行的初始化代码是最远的祖先,然后从顶向下的类继承,所有类都有机会执行他们特定的初始化代码。这样,你在你做你的特定的初始化工作前,所有你从超类继承的东西是不可用的状态。即使它的状态不明确,所有 Apple 的框架的 Framework 是保证遵守这个约定的,而且你的类也应该这样做
实际上这意味着第一个执行的初始化代码是最远的祖先,然后从顶向下的类继承,所有类都有机会执行他们特定初始化代码。这样,你在做特定初始化工作前,所有从超类继承的东西都是不可用的状态。 虽然这没有明确的规定,但是所有 Apple 的框架都保证遵守这个约定,你的类也应该这样做
当定义一个新类的时候有三个不同的方式:
Expand All @@ -650,9 +650,9 @@ designated 初始化方法是提供所有的参数,secondary 初始化方法
第一个方案是最简单的:你不需要增加类的任何初始化逻辑,只需要依照父类的designated initializer。
当你希望提供额外的初始化逻辑的时候,你可以重载 designated initializer。你只需要重载你的直接的超类的 designated initializer 并且确认你的实现调用了超类的方法。
当你希望提供额外的初始化逻辑的时候,你可以重载 designated initializer。你只需要重载直接超类的 designated initializer 并且确认你的实现调用了超类的方法。
你一个典型的例子是你创造`UIViewController`子类的时候重载`initWithNibName:bundle:`方法。
一个典型的例子是你创造`UIViewController`子类的时候重载`initWithNibName:bundle:`方法。
```objective-c
@implementation ZOCViewController
Expand All @@ -670,18 +670,18 @@ designated 初始化方法是提供所有的参数,secondary 初始化方法
@end
```

`UIViewController` 子类的例子里面如果重载 `init` 会是一个错误,这个情况下调用者会尝试调用 `initWithNib:bundle` 初始化你的类,你的类实现不会被调用。着同样违背了它应该是合法调用任何 designated initializer 的规则。
`UIViewController` 子类的例子里面如果重载 `init` 会是一个错误,这个情况下调用者会尝试调用 `initWithNib:bundle` 初始化你的类,你的类实现不会被调用。这同样违背了它应该是合法调用任何 designated initializer 的规则。


在你希望提供你自己的初始化函数的时候,你应该遵守这三个步骤来保证正确的性
在你希望提供你自己的初始化函数的时候,你应该遵守这三个步骤来保证获得正确的行为


1. 定义你的 designated initializer,确保调用了直接超类的 designated initializer。
2. 重载直接超类的 designated initializer。调用你的新的 designated initializer。
3. 为新的 designated initializer 写文档。


很多开发者忽略了后两步,这不仅仅是一个粗心的问题,而且这样违反了框架的规则,而且可能导致不确定的行为和bug
很多开发者忽略了后两步,这不仅仅是一个粗心的问题,而且这样违反了框架的规则,可能导致不确定的行为和bug
让我们看看正确的实现的例子:

```objective-c
Expand All @@ -708,7 +708,7 @@ designated 初始化方法是提供所有的参数,secondary 初始化方法
```
如果你没重载 `initWithNibName:bundle:` ,而且调用者决定用这个方法初始化你的类(这是完全合法的)。 `initWithNews:` 永远不会被调用,所以导致了不正确的初始化流程,你的类特定的初始化逻辑没有被执行
如果你没重载 `initWithNibName:bundle:` ,而且调用者决定用这个方法初始化你的类(这是完全合法的)。 `initWithNews:` 永远不会被调用,所以导致了不正确的初始化流程,你的类的特定初始化逻辑没有被执行
Expand All @@ -717,7 +717,7 @@ designated 初始化方法是提供所有的参数,secondary 初始化方法
你应该考虑来用这两个策略(不是互斥的):第一个是你在文档中明确哪一个初始化方法是 designated 的,你可以用编译器的指令 `__attribute__((objc_designated_initializer))` 来标记你的意图。
用这个编译指令的时候,编译器会来帮你。如果你的新的 designate initializer 没有调用你超类的 designated initializer,那么编译器会发出警告。
用这个编译指令的时候,编译器会来帮你。如果你的新的 designate initializer 没有调用超类的 designated initializer,那么编译器会发出警告。
然而,当没有调用类的 designated initializer 的时候(并且依次提供必要的参数),并且调用其他父类中的 designated initialize 的时候,会变成一个不可用的状态。参考之前的例子,当实例化一个 `ZOCNewsViewController` 展示一个新闻而那条新闻没有展示的话,就会毫无意义。这个情况下你应该只需要让其他的 designated initializer 失效,来强制调用一个非常特别的 designated initializer。通过使用另外一个编译器指令 `__attribute__((unavailable("Invoke the designated initializer"))) ` 来修饰一个方法,通过这个属性,会让你在试图调用这个方法的时候产生一个编译错误。
Expand All @@ -741,11 +741,11 @@ designated 初始化方法是提供所有的参数,secondary 初始化方法

不过一个例外是一个对象是否遵守 `NSCoding` 协议,并且它通过方法 `initWithCoder:` 初始化。
我们应该看超类是否符合 `NSCoding` 协议来区别对待。
如果符合,如果你只是调用 `[super initWithCoder:]`你会可能有一个共享的初始化代码在 designated initializer 里面,一个好的方法是把这些代码放在私有方法里面(比如 `p_commonInit` )。
当你的超类不符合`NSCoding` 协议的时候,推荐把 `initWithCoder:` 作为 secondary initializer 来对待,并且调用 `self` 的 designated initializer。 注意这是违反 Apple [Archives and Serializations Programming Guide](https://developer.apple.com/library/mac/documentation/cocoa/Conceptual/Archiving/Articles/codingobjects.html#//apple_ref/doc/uid/20000948-BCIHBJDE) 上面写的
符合的时候,如果你只是调用 `[super initWithCoder:]`你可能需要在 designated initializer 里面写一些通用的初始化代码,处理这种情况的一个好方法是把这些代码放在私有方法里面(比如 `p_commonInit` )。
当你的超类不符合 `NSCoding` 协议的时候,推荐把 `initWithCoder:` 作为 secondary initializer 来对待,并且调用 `self` 的 designated initializer。 注意这违反了 Apple 写在 [Archives and Serializations Programming Guide](https://developer.apple.com/library/mac/documentation/cocoa/Conceptual/Archiving/Articles/codingobjects.html#//apple_ref/doc/uid/20000948-BCIHBJDE) 上面的规定


> the object should first invoke its superclass's designated initializer to initialize inherited state (对象总是应该首先调用超类的 designated initializer 来初始化继承的状态)
> the object should first invoke its superclass's designated initializer to initialize inherited state(对象总是应该首先调用超类的 designated initializer 来初始化继承的状态)

如果你的类不是 `NSObject` 的直接子类,这样做的话,会导致不可预测的行为。
Expand Down

0 comments on commit d84b935

Please sign in to comment.