`
慭慭流觞
  • 浏览: 44054 次
  • 性别: Icon_minigender_1
  • 来自: 河南
社区版块
存档分类
最新评论

instancetype id

    博客分类:
  • iOS
阅读更多

Objective-C is a rapidly evolving language, in a way that you just don't see in established programming languages. ARC, object literals, subscripting, blocks: in the span of just three years, so much of how we program in Objective-C has been changed (for the better).

All of this innovation is a result of Apple's philosophy of vertical integration. Just as Apple's investment in designing its own chipsets gave them leverage to compete aggressively with their mobile hardware, so too has their investment in LLVM allowed their software to keep pace.

Clang developments range from the mundane to paradigm-changing, but telling the difference takes practice. Because we're talking about low-level language features, it's difficult to understand what implications they may have higher up with API design.

One such example is instancetype, the subject of this week's article.


In Objective-C, conventions aren't just a matter of coding best-practices, they are implicit instructions to the compiler.

For example, alloc and init both have return types of id, yet in Xcode, the compiler makes all of the correct type checks. How is this possible?

In Cocoa, there is a convention that methods with names like alloc, or init always return objects that are an instance of the receiver class. These methods are said to have a related result type.

Class constructor methods, although they similarly return id, don't get the same type-checking benefit, because they don't follow that naming convention.

You can try this out for yourself:

[[[NSArray alloc] init] mediaPlaybackAllowsAirPlay]; // ❗ "No visible @interface for `NSArray` declares the selector `mediaPlaybackAllowsAirPlay`"
//alloc and init 将会根据命名约定返回“相关结果类型”(此处是NSArray)
[[NSArray array] mediaPlaybackAllowsAirPlay]; // (No error before ios7,while it will be error after ios7,because 
// the method array return instancetype after ios7 and the error is the same to above
)
//array 不遵守命名约定,返回id类型,所以如果返回值为id类型,那么在此处就不会有错误,如果返回值为instancetype就会出错,ios7对这点bug做了改进的
//after ios7
+ (instancetype)array
//before ios7
+(id)array
//so you see the difference!

Because alloc and init follow the naming convention for being a related result type, the correct type check against NSArray is performed. However, the equivalent class constructor array does not follow that convention, and is interpreted as id.

id is useful for opting-out of type safety, but losing it when you do want it sucks.

The alternative, of explicitly declaring the return type ((NSArray *) in the previous example) is a slight improvement, but is annoying to write, and doesn't play nicely with subclasses.

This is where the compiler steps in to resolve this timeless edge case to the Objective-C type system:

instancetype is a contextual keyword that can be used as a result type to signal that a method returns a related result type. For example:

@interface Person
+ (instancetype)personWithName:(NSString *)name;
@end

instancetype, unlike id, can only be used as the result type in a method declaration.

With instancetype, the compiler will correctly infer that the result of +personWithName: is an instance of a Person.

Look for class constructors in Foundation to start using instancetype in the near future. New APIs, such as UICollectionViewLayoutAttributes are using instancetype already.

Further Implications

Language features are particularly interesting because, again, it's often unclear of what impact they'll have on higher-level aspects of software design.

While instancetype may seem to be a rather mundane, albeit welcome addition to the compiler, it can be used to some rather clever ends.

Jonathan Sterling wrote this quite interesting article, detailing how instancetype could be used to encode statically-typed collections, without generics:

NSURL <MapCollection> *sites = (id)[NSURL mapCollection];
[sites put:[NSURL URLWithString:@"http://www.jonmsterling.com/"]
        at:@"jon"];
[sites put:[NSURL URLWithString:@"http://www.nshipster.com/"]
        at:@"nshipster"];

NSURL *jonsSite = [sites at:@"jon"]; // => http://www.jonmsterling.com/

Statically-typed collections would make APIs more expressive--no longer would a developer be unsure about what kinds of objects are allowed in a collection parameter.

 
分享到:
评论

相关推荐

    instanceof和typeof运算符的区别详解

    两个运算符虽然比较相似,其实区别还是非常大的,虽然不难区别,但是对于初学者可能稍有困扰,下面就简单介绍一下它们两者的区别,希望对需要的朋友有所帮助

    LNInterpolation:可可和可可触摸的插值框架

    - ( instancetype )interpolateToValue:( id )toValue progress:( double )progress behavior:(LNInterpolationBehavior)behavior; Swift public func interpolate(to toValue: Any, progress: Double) -&gt; Self ...

    分页效果设置

    @protocol ZSegmentedControlDelegate ...@property (nonatomic, weak)id &lt;ZSegmentedControlDelegate&gt; delegate; //@property (nonatomic, copy) void (^indexChangeBlock)(NSUInteger index);

    DMAppearance

    @end@implementation MyObject+ ( instancetype ) appearance{ return ( id )[DMAppearanceRecorder appearanceRecorderForClass: self ];}@end然后,当您的对象准备好接受外观样式时,您可以调用: [...

    ZYGCD计时器:GCD计时器

    ZYGCDTimer ZYGCDTimer主要用于替代NSTimer ,不会强持有目标,基于进行修改的,本质上是...+ ( instancetype )timerWithTimeInterval:( NSTimeInterval )interval target:( id )aTarget selector:( SEL )aSelector

    一个支持图文混排的ActionSheet

    - (instancetype)initWithTitle:(NSString *)title delegate:(id)delegate cancelButtonTitle:(NSString *)cancelButtonTitle destructiveButtonTitle:(NSString *)destructiveButtonTitle otherButtonTitles:...

    CKComponentFadeTransition:用于添加淡入淡出过渡的 ComponentKit 扩展

    CKComponentFadeTransition ...+ ( instancetype )newWithURL:( NSURL *)url imageDownloader:( id )imageDownloader scenePath:( id )scenePath size:( const CKComponentSize &)size options:( const

    导航选项的菜单控件

    @property (weak, nonatomic) id delegate; @property (strong, nonatomic) UIColor *textColor; @property (strong, nonatomic) UIColor *separatarColor; - (instancetype)initWithItems:(NSArray *)items ...

    粒子云框架

    粒子云框架 粒子云框架是一种云资源供应框架,可以完全自定义和扩展,可以通过代码调用,并且不需要手动维护资源状态。 粒子云框架可实现对分层云基础架构进行建模,自动化部署以及管理... "InstanceType": "t2.micro",

    ios-封装了FMDB,用户只需要关心字段和字段值,逻辑完全不要关心,用起来及其方便快捷,非常适合新手.zip

    (instancetype)intance; /** 数据库中是否存在表 */ - (BOOL)isExistWithTableName:(NSString*)name; /** 默认建立主键id 创建表(如果存在则不创建) , keys 数据存放要求@[字段名称1,字段名称2] */ ...

    CRLoom:用于在核心数据中线程化NSManagedObject创建,更新和查询的框架

    概述NSManagedObjectImportOperation 这是通过创建的NSOperation子类+ (instanceType)operationWithData:( id )data managedObjectClass:( Class )class guaranteedInsert:( BOOL )guaranteedInsert saveOnBatchSize...

    ABCounterViewController:具有递增和递减功能的简约计数器控件

    应使用指定的初始化程序创建 ABCounterViewController 的实例: -(instancetype) initWithDelegate:(id&lt;ABCounterViewController)delegate startCount:(float)startCount minCount:(float)minCount maxCount:...

    iOS中UIAlertView警告框组件的使用教程

    – (instancetype)initWithTitle:(NSString *)title message:(NSString *)message delegate:(id /**/)delegate cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles,...

    WSChartView:绘制折线图或条形图的框架

    介绍WSChartView WSLineChartView WSBarChartView WSData WSBar WSLabel用法在里面- (instancetype)initWithFrame:(CGRect)frame WithChartViewStyle:(WSChartViewStyle)Style WithDataSource:(id)source;...

    Android实现根据评分添加星级条

    简述 在仿写豆瓣的时候,发现了根据评分不同,星级数也不同的星级条。 百度一搜,发现Android有自带控件UIRatingBar,而iOS得要自己写…好吧,那就写吧。 图片素材 ...- (instancetype)initWithFram

Global site tag (gtag.js) - Google Analytics