OC为何很少new一个对象?

image.png

前言

对于OC,我们最常用的生成一个对象的方式是下面这样的

NSObject *obj = [[NSObject alloc] init];

当然也会有下面这种方式

NSObject *obj = [NSObject new];

但是这种方式是很少用的。对于大部分人的理解,其实new的效果和结果是和alloc组合init是一样的,那么既然如此,为何大家均选择了调用两个方法的稍微复杂点的方式,而并没选择调用一个方法new的简单方式呢?

OC为何很少new一个对象?

苹果官方解释

下面是苹果官方文档

Type Method

# new

Allocates a new instance of the receiving class, sends it an [init] 
message, and returns the initialized object.

Framework

*   Objective-C Runtime

## Declaration

+ (instancetype)new;

## Return Value

A new instance of the receiver.

## Discussion

This method is a combination of [alloc] and [init]. Like [alloc], it 
initializes the `isa` instance variable of the new object so it points to 
the class data structure. It then invokes the [init] method to complete 
the initialization process.

关键则是后面的两句

Allocates a new instance of the receiving class, sends it an [init] 
message, and returns the initialized object.
//生成一个新的实例对象,并发送一个[init]方法,然后返回初始化过的对象
This method is a combination of [alloc] and [init]. Like [alloc], it 
initializes the `isa` instance variable of the new object so it points to 
the class data structure. It then invokes the [init] method to complete 
the initialization process.
//[new]方法是后面两个方法的结合,也就是:[alloc]和[init].  [alloc]:
初始化一个新对象的isa实例变量,并且指向其对应的类数据结构。然后调用[init]方法去完成初始化过程

从解释可以看出,[new]方法是后面两个方法的结合,也就是:[alloc]和[init]。并且作用也是和这两个方法是一样的。从权威的官方文档解释,我们仍然看不出两者之间的区别。

GNUstep解释

偶然间,我在另一个权威的代码文档中发现了他们之间的不同点,那就是GNUstep。GNUstep是GNU对OC的开源,可以说是除苹果外,对于OC最权威以及正确的一份代码资料了。下面则是GNUstep对于new的解释

/**
 *   This method is a short-hand for alloc followed by init, that is,
 *    NSObject *object = [NSObject new];

 * is exactly the same as
 *    NSObject *object = [[NSObject alloc] init];

 *   This is a general convention: all <code>new...</code>
 *   methods are supposed to return a newly allocated and
 *   initialized instance, as would be generated by an
 *   <code>alloc</code> method followed by a corresponding
 *   <code>init...</code> method.  Please note that if you are
 *   not using a garbage collector, this means that instances
 *   generated by the <code>new...</code> methods are not
 *   autoreleased, that is, you are responsible for releasing
 *   (autoreleasing) the instances yourself.  So when you use
 *   <code>new</code> you typically do something like:

 *      NSMutableArray *array = AUTORELEASE ([NSMutableArray new]);

 *   You do not normally need to override <code>new</code> in
 *   subclasses, because if you override <code>init</code> (and
 *   optionally <code>allocWithZone:</code> if you really
 *   need), <code>new</code> will automatically use your
 *   subclass methods.

 *   You might need instead to define new <code>new...</code>
 *   methods specific to your subclass to match any
 *   <code>init...</code> specific to your subclass.  For
 *   example, if your subclass defines an instance method

 *   initWithName:

 *   it might be handy for you to have a class method

 *    newWithName:

 *   which combines <code>alloc</code> and
 *   <code>initWithName:</code>.  You would implement it as follows:


 *     + (id) newWithName: (NSString *)aName
 *     {
 *       return [[self alloc] initWithName: aName];
 *     }
 */
+ (id) new
{
  return [[self alloc] init];
}

我给大家找出了关键点,如下

 *   Please note that if you are
 *   not using a garbage collector, this means that instances
 *   generated by the <code>new...</code> methods are not
 *   autoreleased, that is, you are responsible for releasing
 *   (autoreleasing) the instances yourself.  So when you use
 *   <code>new</code> you typically do something like:

 *      NSMutableArray *array = AUTORELEASE ([NSMutableArray new]);

这句话的意思很明显了,就是说,如果你没使用垃圾回收(这里的意思是指,ARC,因为OC一直是一门具有垃圾回收机制的一门语言)的话,也就是在MRC下,使用new生成的实例对象,将不会自动释放,将由你手动管理对象的release。
其实我理解这句话的意思就是,如果在MRC下,使用new的时候,写代码的话,主要就得写成下面这样:

NSMutableArray *array = AUTORELEASE ([NSMutableArray new]);

这样的写法也是和普通的写法有很大不同的,之后现在在来看看这个AUTORELEASE


image.png

从图中可以看到:AUTORELEASE函数的这种隐式声明早已经在c99就不合法了。

最终解释

OC是一门上世纪八十年代就诞生的一门语言,但是ARC则是Xcode4开始才支持的,而Xcode4则是在2011年才发布的。也就是说,在长达接近三十年的时间里,OC都是在MRC下编写代码的,从上面GNU文档里的解释可以看出:
1、在MRC下,new的对象release方式的不同点,因此大家就选择了相对复杂的[alloc]和[init]的组合方式,并在长达三十年的代码风格中形成了风俗和习惯,并衍生至今。
2、当然,如果用new生成一个对象的话,那么初始化方法就只能调用到init,而不能调用到自定义的initWith等方法,然而我们实际开发中,却常自定义init方法,因此new就在此种情况下不太合适

image.png

image.png

从上面文档解释也能知道的一点是:在如今的ARC下,其实[new]和[[alloc] init]是没什么区别的,从官方文档的解释和GNU源码也能看得出来,他两是一样的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容