Objective-C一些很有用的特性(转载)

2016-08-23  本文已影响432人  __LuckyPan__

原博客地址

Objective-C 很有用的特性

总结一下 Objective-C 的一些不太常用但是很有用的特征,有些特性是为了和 Swift 统一,不过对日常开发都是非常有益的~
Modules

新的编译符号@import

@import UIKit.UIView;

编译优化,避免编译时重复引用,增加编译速度。
参考:WWDC 2013 Session笔记 - Xcode5和ObjC新特性

Nullability
常规用法

@property (nonatomic, strong, nonnull) Sark *sark;
@property (nonatomic, copy, readonly, nullable) NSArray *friends;
+ (nullable NSString *)friendWithName:(nonnull NSString *)name;

修饰变量,前面需要加双下划线,比如 block 内用法:

  • (void)startWithCompletionBlock:(nullable void (^)(NSError * __nullable error))block;

setter 用法,参见 UIViewController 中的 view 属性,它可以被设成 nil,但是调用 getter 时会触发 -loadView 从而创建并返回一个非 nil 的 view。

@property (null_resettable, nonatomic, strong) UIView *view;

宏的用法(包在宏里面的对象默认加 nonnull 修饰符,只需要把 nullable 的指出来就行):

NS_ASSUME_NONNULL_BEGIN
@interface Sark : NSObject
@property (nonatomic, copy, nullable) NSString *workingCompany;
@property (nonatomic, copy) NSArray *friends;- (nullable NSString *)gayFriend;
@end
NS_ASSUME_NONNULL_END

Nullability 主要作用是在编译器层面提供了空值的类型检查,在类型不符时给出 warning,方便开发者第一时间发现潜在问题。
参考:
iOS开发~Objective-C新特性
2015 Objective-C 新特性
__kindof
主要作用还是编译器层面的类型检查
>>> // UIView 的写法
@property (nonatomic, readonly, copy) NSArray<__kindof UIView *> *subviews;
// UITableView 的写法
- (nullable __kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier;

参考:
iOS开发~Objective-C新特性
2015 Objective-C 新特性
轻量级的泛型
带泛型的容器
>>>NSArray<NSString *> *strings = @[@"sun", @"yuan"];
NSDictionary<NSString *, NSNumber *> *mapping = @{@"a": @1, @"b": @2};

自定义泛型
>>> @interface Stack<ObjectType> : NSObject
- (void)pushObject:(ObjectType)object;
- (ObjectType)popObject;
@property (nonatomic, readonly) NSArray<ObjectType> *allObjects;@end

还可以增加限制
>>> // 只接受 NSNumber * 的泛型@interface Stack<ObjectType: NSNumber *> : NSObject
// 只接受满足 NSCopying 协议的泛型@interface Stack<ObjectType: id<NSCopying>> : NSObject

covariant && contravariant
__covariant : 子类型可以强转到父类型(里氏替换原则)
__contravariant : 父类型可以强转到子类型(WTF?)

参考 NSArray 和 NSMutableArray 的定义
>>> // NSArray@interface NSArray<__covariant ObjectType> : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration>
@property (readonly) NSUInteger count;
- (ObjectType)objectAtIndex:(NSUInteger)index;
- (instancetype)init NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithObjects:(const ObjectType [])objects count:(NSUInteger)cnt NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;
@end

>>> // NSMutableArray@interface NSMutableArray<ObjectType> : NSArray<ObjectType>
   - (void)addObject:(ObjectType)anObject;- (void)insertObject:(ObjectType)anObject atIndex:(NSUInteger)index;
  - (void)removeLastObject;
  - (void)removeObjectAtIndex:(NSUInteger)index;
  - (void)replaceObjectAtIndex:(NSUInteger)index withObject:(ObjectType)anObject;
  - (instancetype)init NS_DESIGNATED_INITIALIZER;
  - (instancetype)initWithCapacity:(NSUInteger)numItems NS_DESIGNATED_INITIALIZER;
  - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder  NS_DESIGNATED_INITIALIZER;
  @end

参考:
iOS开发~Objective-C新特性
2015 Objective-C 新特性
Designated Initializer
Objective-C 中主要通过NS_DESIGNATED_INITIALIZER宏来实现指定构造器的。
参考 UIViewController 的两个指定构造器:
>>> - (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;

类似 swift 的指定初始化,原则如下(类比 swift 的构造构成):

参考:
iOS Designated Initializers : Using NS_DESIGNATED_INITIALIZER
正确编写Designated Initializer的几个原则

上一篇下一篇

猜你喜欢

热点阅读