Objective-C中的self与LLVM Clang新引入的instancetype
我们知道,大部分面向对象语言对于一个类的成员方法都有一个隐含的参数。在C++、Java、C#和JavaScript中是this,而在Objective-C中则是self。当然,由于Objective-C++要完全兼容标准C++,因此关键字不能与C++有所冲突,所以用了self。
但是,Objective-C中的self与C++、Java等编程语言中的还有一点不同——Objective-C中的self可以用于类方法,而不仅仅是成员方法,这点C++、Java等都无法做到。比如:
@interface MyClass : NSObject + (id)createMyObject; @end @implementation MyClass - (id)init
{
self = [super init]; NSLog(@"Hello, world"); return self;
} + (id)createMyObject
{
MyClass *mc = [[self alloc] init]; return [mc autorelease];
} @end
我们看到,上述代码片段中MyClass类的createMyObject类方法中通过self来调用NSObject的类方法alloc。这里,self指向了createMyObject这个消息所发送给的类。当我们用[MyClass createMyObject]这句语句时,createMyObject中的self其实就指示了MyClass类本身。因此,可以直接用self来调用类方法alloc。
然后利用这个特性,我们结合LLVM Clang新引入的instancetype可以编写出兼容性更强,更灵活方便的工厂方法。下面先介绍一下instancetype。
instancetype其实跟id差不多,但是它跟id不同的是,它表示一个与当前类相兼容的类型,而id则是一个通用的Objective-C对象类型引用类型。因此,如果我们要在一个类方法中返回类型为自身类型的对象,那么返回类型可以写instancetype。而上述代码片段完全符合这个要求,因此我们可以做如下改写:
@interface MyClass : NSObject + (instancetype)createMyObject;
- (void)dummyMethod; @end @implementation MyClass - (id)init
{
self = [super init]; NSLog(@"Hello, world"); return self;
} + (instancetype)createMyObject
{
MyClass *mc = [[self alloc] init]; return [mc autorelease];
} - (void)dummyMethod
{ } @end
这样一来,我们如果这么用:[[MyClass createMyObject] dummyMethod]会非常安全。因为createMyObject方法所返回的对象可确保是与MyClass类相兼容的。
这里需要注意的是instancetype只能用作为返回类型,不允许作为参数或用于定义临时变量。
我们下面将提供一个结合self特性与instancetype特性的工厂方法:
@interface MyClass : NSObject + (instancetype)createMyObject;
- (void)dummyMethod; @end @interface MySubClass : MyClass @end @implementation MyClass - (id)init
{
self = [super init]; NSLog(@"Hello, world"); return self;
} + (instancetype)createMyObject
{
MyClass *mc = [[self alloc] init]; return [mc autorelease];
} - (void)dummyMethod
{ } @end @implementation MySubClass - (id)init
{
self = [super init]; NSLog(@"Hi, world!"); return self;
} - (void)dummyMethod
{
NSLog(@"I am a child.");
} @end
你可以调用[[MySubClass createMyObject] dummyMethod],可以看看输出结果。
此时,你会有个疑问,我直接用MyClass *myObj = [[MySubClass alloc] init];不也一样可以嘛,需要那么复杂吗?
当然,C++、Java等编程语言都是这么做的。而Objective-C目前有两种状态,一种是MRC(Manual Reference Count),另一种是ARC(Auto Reference Count)。这两种模式对于实例创建而言是不一样的。前者创建完了之后,需要调用release,而后者则不需要。因此,我们通过上述讲解的通过类方法来创建autorelease对象来有效地屏蔽应用层接口的统一性问题。我们看到Apple自己在iOS7.0开始可用的框架都大量用了此种方法。这样,通过模版自动生成出来的代码不管是在MRC下还是在ARC下都能正常工作。
Objective-C中的self与LLVM Clang新引入的instancetype的更多相关文章
- llvm+clang编译安装
最近一段时间在llvm+clang上做一些东西,所以顺便将自己如何编译安装llvm+clang写了篇文章发在这里,希望能帮助刚接触llvm+clang的童鞋少走一些弯路(我刚接触的时候为了编译安装这个 ...
- LLVM每日谈21 一些编译器和LLVM/Clang代码
作者:闪亮宁(snsn1984) 一些自己的收藏LLVM/Clang代码,而他自己写一些一点点LLVM/Clang译器的代码.在这里把这些代码库分享出来,欢迎大家交流探讨. 1.crange http ...
- Sublime Text3 & MinGW & LLVM CLang 安装配置C-C++编译环境
Sublime Text是一款强大的跨平台代码编辑器,小巧而且丰富实用的功能是Visual Studio不能比拟的,但是编译运行是一个软肋,本文通过在sublime中配置g++编译器实现程序的编译功能 ...
- 理解Objective C 中id
什么是id,与void *的区别 id在Objective C中是一个类型,一个complier所认可的Objective C类型,跟void *是不一样的,比如一个 id userName, 和vo ...
- 浅谈Objective—C中的面向对象特性
Objective-C世界中的面向对象程序设计 面向对象称程序设计可能是现在最常用的程序设计模式.如何开发实际的程序是存在两个派系的-- 面向对象语言--在过去的几十年中,很多的面向对象语言被发明出来 ...
- objective C中的字符串NSStirng常用操作
objective C中的字符串操作 在OC中创建字符串时,一般不使用C的方法,因为C将字符串作为字符数组,所以在操作时会有很多不方便的地方,在Cocoa中NSString集成的一些方法,可以很方便的 ...
- Linux c++ vim环境搭建系列(2)——Ubuntu18.04.4编译安装llvm clang
2. 源码编译安装llvm clang 参考网址: https://llvhttps
- php中禁止非法调用和硬路径引入文件的方法
php中禁止非法调用和硬路径引入文件的方法 在php中有一些公共的文件为了方便,我们会做一个公共文件,让不用的文件共同调用.为了禁止公共文件被非常单独调用,可以在文件上做一个常量,禁止非常调用:在公共 ...
- 擦他丫的,今天在Django项目中引用静态文件jQuery.js 就是引入报错,终于找到原因了!
擦 ,今天在Django项目中引用静态文件jQuery.js 就是引入报错,终于找到原因了! 问题在于我使用的谷歌浏览器,默认使用了缓存,导致每次访问同一个url时,都返回的是缓存里面的东西.通过谷歌 ...
随机推荐
- inotify和rsync实现数据实时同步
数据的实时同步 实现实时同步 要利用监控服务(inotify),监控同步数据服务器目录中信息的变化 发现目录中数据产生变化,就利用rsync服务推送到备份服务器上 实现实时同步的方法 ino ...
- MySQL数据库的二进制安装、源码编译和基础入门操作
一.MySQL安装 (1)安装方式: 1 .程序包yum安装 优点:安装快,简单 缺点:定死了各个文件的地方,需要修改里边的相关配置文件,很麻烦 2 .二进制格式的程序包:展开至特定路径,并经过简单配 ...
- 用Python来使用科大讯飞语音识别,so easy
在人工智能高速发展的今天,语音识别技术被带入到人们的工作和生活中,开始被越来越多的人关注和使用,今天,当各种在线客服被机器人客服代替,当速记翻译馆被语音识别代替,甚至当收银员.驾驶员.工厂工人.普通文 ...
- Mybatis报错: There is no getter for property named xxx
在mapper文件中函数的形参上加上注解. 例如: 出现了如下错误:核心错误提示就是There is no getter for property named xxx ### Error qu ...
- 各位大佬Python的第一部分道基础题已经整理好了,希望大家面试的时候能用的上。
Python的第一部分道基础题,希望大家面试的时候能用的上. 1.为什么学习Python? Python是目前市面上,我个人认为是最简洁.最优雅.最有前途.最全能的编程语言,没有之一. 2.通过什么途 ...
- 《构建之法》——Alpha2项目的测试
这个作业属于哪个课程 课程的链接 这个作业要求在哪里 作业要求的链接 团队名称 Runningman 这个作业的目标 测试其他组的项目,互相借鉴 作业正文 作业正文 测试人姓名 陈嘉莹 测试人学号 2 ...
- 【NOIP/CSP2019】D2T1 Emiya 家今天的饭
这个D2T1有点难度啊 原题: 花了我一下午的时间,作为D2T1的确反常 条件很奇怪,感觉不太直观,于是看数据范围先写了个暴力 写暴力的时候我就注意到了之前没有仔细想过的点,烹饪方式必须不同 虽然a很 ...
- CodeForces 768E SG函数 整数划分 Game of Stones
一个标准的NIM游戏 加上一条规则:每堆石子对于每个数目的石子只能被取一次 可以SG打表 dp[i][j]表示现在有i个石子 j是可以取的石子数的状压 第i位为1就表示i个石子没被取过 #includ ...
- Mysql 随机获得表的几条记录
在做博客文章详情的时候,有一个拓展阅读的功能: 想法一:根据当前文章Id,写死两条链接,Id+1,Id-1,但是文章Id可能被删除,Id不连续,不可取.× 想法二:获得当前文章记录的前一条和后一条记录 ...
- [唐胡璐]Selenium技巧 - 定制元素属性检查,并写到ReportNG中
QTP 和Selenium 都会有这种要检查某一个控件元素属性的情况,比如去检查一个Button的显示文字是什么? 为了更方便的书写程序,并优美的显示到HTML测试报告中,做了以下几个小小的封装,只是 ...