Objective-C很有用的特性

独奏

技术分享|2015-9-16|最后更新: 2023-2-23|
type
status
date
slug
summary
tags
category
icon
password
总结一下 Objective-C 的一些不太常用但是很有用的特征,有些特性是为了和 Swift 统一,不过对日常开发都是非常有益的~

Modules

新的编译符号@import
编译优化,避免编译时重复引用,增加编译速度。

Nullability

常规用法
修饰变量,前面需要加双下划线,比如 block 内用法:
setter 用法,参见 UIViewController 中的 view 属性,它可以被设成 nil,但是调用 getter 时会触发 -loadView 从而创建并返回一个非 nil 的 view。
宏的用法(包在宏里面的对象默认加 nonnull 修饰符,只需要把 nullable 的指出来就行):
Nullability 主要作用是在编译器层面提供了空值的类型检查,在类型不符时给出 warning,方便开发者第一时间发现潜在问题。

__kindof

主要作用还是编译器层面的类型检查

轻量级的泛型

带泛型的容器

自定义泛型

还可以增加限制

covariant && contravariant

  • __covariant : 子类型可以强转到父类型(里氏替换原则)
  • __contravariant : 父类型可以强转到子类型(WTF?)
参考 NSArray 和 NSMutableArray 的定义

Designated Initializer

Objective-C 中主要通过NS_DESIGNATED_INITIALIZER宏来实现指定构造器的。
参考 UIViewController 的两个指定构造器:
类似 swift 的指定初始化,原则如下(类比 swift 的构造构成): - 每个类的正确初始化过程应当是按照从子类到父类的顺序,依次调用每个类的Designated Initializer。并且用父类的Designated Initializer初始化一个子类对象,也需要遵从这个过程。 - 如果子类指定了新的初始化器,那么在这个初始化器内部必须调用父类的Designated Initializer。并且需要重写父类的Designated Initializer,将其指向子类新的初始化器。 - 你可以不自定义Designated Initializer,也可以重写父类的Designated Initializer,但需要调用直接父类的Designated Initializer。 - 如果有多个Secondary initializers(次要初始化器),它们之间可以任意调用,但最后必须指向Designated Initializer。在Secondary initializers内不能直接调用父类的初始化器。 - 如果有多个不同数据源的Designated Initializer,那么不同数据源下的Designated Initializer应该调用相应的[super (designated initializer)]。如果父类没有实现相应的方法,则需要根据实际情况来决定是给父类补充一个新的方法还是调用父类其他数据源的Designated Initializer。比如UIView的initWithCoder调用的是NSObject的init。 - 需要注意不同数据源下添加额外初始化动作的时机。