`

new 与 alloc/init的区别

阅读更多

http://blog.csdn.net/abby_sheen/article/details/7818797

 

英文详解:http://macresearch.org/difference-between-alloc-init-and-new

我也是转来的:http://blog.csdn.net/ch_soft/article/details/7387731

1.在实际开发中很少会用到new,一般创建对象咱们看到的全是[[className alloc] init]
    但是并不意味着你不会接触到new,在一些代码中还是会看到[className new],
    还有去面试的时候,也很可能被问到这个问题。

2.那么,他们两者之间到底有什么区别呢,

我们看源码:

-------------------------------------------------------

+ new
{
id newObject = (*_alloc)((Class)self, 0);
Class metaClass = self->isa;
if (class_getVersion(metaClass) > 1)
    return [newObject init];
else
    return newObject;
}
-------------------------------------------------------

而 alloc/init 像这样:

-------------------------------------------------------

+ alloc
{
return (*_zoneAlloc)((Class)self, 0, malloc_default_zone()); 
}

- init
{
    return self;
}
-------------------------------------------------------

通过源码中我们发现,[className new]基本等同于[[className alloc] init];
区别只在于alloc分配内存的时候使用了zone.
这个zone是个什么东东呢?
它是给对象分配内存的时候,把关联的对象分配到一个相邻的内存区域内,以便于调用时消耗很少的代价,提升了程序处理速度;

3.而为什么不推荐使用new?

不知大家发现了没有:如果使用new的话,初始化方法被固定死只能调用init.
而你想调用initXXX怎么办?没门儿!据说最初的设计是完全借鉴Smalltalk语法来的。
传说那个时候已经有allocFromZone:这个方法,
但是这个方法需要传个参数id myCompanion = [[TheClass allocFromZone:[self zone]] init];

这个方法像下面这样:
--------------------------------------------------------
+ allocFromZone:(void *) z
{
return (*_zoneAlloc)((Class)self, 0, z); 
}
--------------------------------------------------------

后来简化为下面这个:
------------------------------------------------------------
+ alloc
{
return (*_zoneAlloc)((Class)self, 0, malloc_default_zone()); 
}
-------------------------------------------------------------

但是,出现个问题:这个方法只是给对象分配了内存,并没有初始化实例变量。
是不是又回到new那样的处理方式:在方法内部隐式调用init方法呢?
后来发现“显示调用总比隐式调用要好”,所以后来就把两个方法分开了。

概括来说,new和alloc/init在功能上几乎是一致的,分配内存并完成初始化。

差别在于,采用new的方式只能采用默认的init方法完成初始化,

                    采用alloc的方式可以用其他定制的初始化方法。

分享到:
评论

相关推荐

    IOS 中 new 和 alloc init 的对比

    在iOS的Objective-C编程中,`new`和`alloc` `init`是两种常见的对象创建方式,虽然它们在大多数情况下可以达到相同的效果,但还是存在一些细微的差异和使用场景上的不同。 首先,`new`关键字在Objective-C中实际上...

    ios-iOS 未读消息角标 仿QQ拖拽 简单灵活 支持xib(源码).zip

    _badge1 = [[LFBadge alloc] init]; [_badge1 addToTabBarItem:_view1]; //BarButtonItem上加角标 _badge2 = [[LFBadge alloc] init]; [_badge2 addToBarButtonItem:self.navigationItem.rightBarButtonItem];...

    UIKit+Abstract-Factory

    UIButton *button = [[UIButton alloc] init]; // 自定义配置 return button; } - (UILabel *)createLabel { UILabel *label = [[UILabel alloc] init]; // 自定义配置 return label; } // ... @end ``` 3. *...

    ios初级笔记

    Student *stu=[[student alloc] init]; //释放方法 [stu release] [stu setAge:20 andNo:3] NSLog(@"this age is:i% andNo:i%",[stu age],[stu no]) } return 0; } 2.点语法 以1为实例: stu.age ...

    小议iOS内存管理-中文.pdf

    `init`, `new`, 和 `copy` 方法会增加引用计数。当对象不再被任何指针引用,即引用计数降为零时,系统将调用`dealloc`方法彻底销毁对象。 内存泄露通常发生在对象被创建后,虽然不再需要但未能正确减少引用计数至零...

    iphone开发快速入门[收集].pdf

    MyClass *strongInstance = [[MyClass alloc] init]; // 强类型 id weakInstance = [[MyClass alloc] init]; // 弱类型 ``` Objective-C的消息传递机制允许直接使用消息结果,减少了临时变量的使用,提高效率。例如...

    objective-c 内存管理Demo

    非ARC环境下,正确的内存管理遵循"谁创建,谁释放"的原则,即谁调用了`alloc`或`new`、`copy`、`retain`,谁就应该负责调用`release`或`autorelease`。 4. **retain**: `retain`方法用于增加对象的引用计数,通常...

    InputPasswordLikeAlipay-源码

    添加密码输入完成代理3.new a ZSDPaymentView instance:新建一个ZSDPaymentView实例ZSDPaymentView *payment = [[ZSDPaymentView alloc]init];payment.title = @"支付密码标题";payment.goodsName = @"商品名称";...

    Iphone数组一些基础操作 NSArray/NSMutableArray

    NSMutableArray *newArray = [NSMutableArray alloc] init]; NSArray *oldArray = [NSArray arrayWithObjects:@"a",@"b",@"c",@"d",@"e",@"f",@"g",@"h",nil]; for(int i = 0; i [oldArray count]; i++) { id obj =...

    本地存储NSUserdefault封装(可存储各种类型)

    StudentModel *student = [[StudentModel alloc] init]; student.name = @"A"; NSArray *array = @[[InfoModel new], [InfoModel new], [InfoModel new]]; student.datas = array; [student localStoreWithKey:...

    Objective C 单例模式设计源码

    第一种方式,用new方法初始化其实是第二种方式的总和,当调用new方法时,其实是先调用了alloc方法进行isa(is a pointer)操作,创建指针,指向内存中的数据结构,紧接着调用了init方法对数据进行初始化,NSObject类...

    单例的代码

    4. 防止其他对象通过`alloc-init`方式创建实例,重写`init`方法并抛出异常。 下面是一个简单的Objective-C单例模式的实现示例: ```objc // SingleTon.h #import <Foundation/Foundation.h> @interface SingleTon...

    OC-工厂模式-处理不同通知

    实例是类的具体实现,通过`alloc`和`init`方法创建。工厂模式的核心就是创建这些实例,但不暴露具体的创建过程给客户端。 ### 3. 通知系统 在iOS中,Notification Center是负责处理应用内消息传递的机制。开发者...

    iPhone Mac Objective-C内存管理教程和原理剖析

    6. retain、release、autorelease 的关系:当你调用 alloc、new、copy 或 mutableCopy 方法创建对象时,对象的 retain count 会增加 1。这时,你需要通过 release 或 autorelease 来平衡这一增加。如果你从其他对象...

    iphone存储用法汇总

    - 使用`alloc`和`init`方法:`NSString *astring = [[NSString alloc] init];` - 使用`initWithString:`方法:`NSString *astring = [[NSString alloc] initWithString:@"This is a String!"];` - 使用`...

    ARC到底帮我们做了哪些工作?(v1.3)

    - **创建对象**:当你使用`alloc/init`或者`new`关键字创建一个对象时,其引用计数为1。 - **赋值操作**:当你将一个对象赋值给另一个变量或属性时,目标对象的引用计数增加1。 - **强引用循环**:当两个或多个对象...

    iphone NSBundle 详解

    id instance = [[newClass alloc] init]; ``` 如果不确定类名,可以通过`principalClass`获取库的主要类: ```objc Class aClass = [NSBundle bundleWithPath:@"LibraryPath"].principalClass]; id instance = [[a...

    Object-C 中将视图控制器加到UIWindow

    UIViewController *rootViewController = [[UIViewController alloc] init]; UIWindow *window = [UIApplication sharedApplication].keyWindow; window.rootViewController = rootViewController; [window ...

    iOS Json 实体类序列化及反序列化

    Person *newPerson = [[Person alloc] init]; newPerson.name = dict[@"name"]; newPerson.age = [dict[@"age"] integerValue]; ``` #### 2. Swift ```swift // JSON字符串 let jsonString = "{\"name\":\"张三\",...

Global site tag (gtag.js) - Google Analytics