iOS 中 new 和 alloc init 的区别

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

1.在实际开发中很少会用到new,一般创建对象咱们看到的全是[[className alloc] init]

但是并不意味着你不会接触到new,在一些代码中还是会看到[className new],

还有去面试的时候,也很可能被问到这个问题。

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

我们看源码:

 
  1. new 
  2. id newObject = (*_alloc)((Class)self, 0); 
  3. Class metaClass = self->isa; 
  4. if (class_getVersion(metaClass) > 1) 
  5. return [newObject init]; 
  6. else 
  7. return newObject; 
  8.  
  9. //而 alloc/init 像这样: 
  10. + alloc 
  11. return (*_zoneAlloc)((Class)self, 0, malloc_default_zone());  
  12. - init 
  13. return self; 

通过源码中我们发现,[className new]基本等同于[[className alloc] init];

区别只在于alloc分配内存的时候使用了zone.

这个zone是个什么东东呢?

它是给对象分配内存的时候,把关联的对象分配到一个相邻的内存区域内,以便于调用时消耗很少的代价,提升了程序处理速度;

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

不知大家发现了没有:如果使用new的话,初始化方法被固定死只能调用init.

而你想调用initXXX怎么办?没门儿!据说最初的设计是完全借鉴Smalltalk语法来的。

传说那个时候已经有allocFromZone:这个方法,

但是这个方法需要传个参数id myCompanion = [[TheClass allocFromZone:[self zone]] init];

这个方法像下面这样:

 
  1. + allocFromZone:(void *) z 
  2. return (*_zoneAlloc)((Class)self, 0, z);  
  3.  
  4. //后来简化为下面这个: 
  5. + alloc 
  6. return (*_zoneAlloc)((Class)self, 0, malloc_default_zone());  

但是,出现个问题:这个方法只是给对象分配了内存,并没有初始化实例变量。

是不是又回到new那样的处理方式:在方法内部隐式调用init方法呢?

后来发现“显示调用总比隐式调用要好”,所以后来就把两个方法分开了。

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

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

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



原文:http://mobile.51cto.com/hot-404891.htm


更多精彩文章,尽在我的公众号.


<think> 我们注意到用户的问题是关于C语言中newinit区别。但是,根据提供的引用C语言本身的特点,我们需要澄清一个重要的前提:**C语言本身并没有内建的`new`运算符或`init`关键字**。 在C语言中: - 动态内存分配通常使用`malloc`、`calloc`等函- 初始化则通过赋值或调用初始化函完成。 然而,用户提供的引用中: - 引用[1]讨论的是Objective-C(iOS开发语言)中的`alloc`、`init``new`,它们用于对象创建初始化。 - 引用[2]提到的是C++中的`new`运算符(C++是C的超集,但C语言本身没有)。 - 引用[3][4]分别讨论了位运算汇编程序,与问题不直接相关。 因此,我们需要明确回答: 1. 如果是针对C语言:没有`new``init`,但可以解释动态内存分配初始化的常规做法。 2. 如果用户指的是类似C++或Objective-C中的概念,则按照相应语言解释。 由于用户问题明确提到“C语言”,但引用中出现了Objective-CC++,我们将重点放在C语言的动态内存分配初始化上,同时简要对比C++Objective-C以澄清误解。 ### 回答结构: 1. **澄清概念**:说明C语言中无`new``init`。 2. **C语言的动态内存分配与初始化**:使用`malloc`初始化函。 3. **对比C++的`new`构造函**:解释C++中的类似机制。 4. **对比Objective-C的`alloc``init`**:解释引用[1]中的内容。 5. **总结区别**:以表格形式对比。 --- ### 1. C语言中无内建的`new``init` 在标准C语言(ANSI C)中,并没有`new`运算符或`init`关键字。动态内存分配使用标准库函`malloc`、`calloc`等,而初始化通常由程序员显式完成,例如通过赋值或调用初始化函。 ### 2. C语言中的动态内存分配与初始化 - **动态分配内存(相当于“创建”)**: 使用`malloc`函分配内存,它只分配指定大小的内存块,不进行初始化(内存中的值是随机的): ```c int *p = (int*)malloc(sizeof(int)); // 分配一个整型的内存空间 ``` 或者使用`calloc`,它会将分配的内存初始化为0: ```c int *arr = (int*)calloc(5, sizeof(int)); // 分配5个整型的组,并初始化为0 ``` - **初始化(相当于“初始化”)**: 程序员需要手动初始化分配的内存: ```c *p = 10; // 初始化分配的整型 for (int i=0; i<5; i++) { arr[i] = i+1; // 初始化组 } ``` 也可以封装一个初始化函: ```c void init_array(int *arr, int size) { for (int i=0; i<size; i++) { arr[i] = i+1; } } ``` ### 3. C++中的`new`构造函(作为对比) C++扩展了C语言,引入了`new`运算符构造函(类似于`init`的概念): - **`new`运算符**:在堆上动态分配对象内存,并调用构造函进行初始化。 ```cpp int *p = new int(10); // 分配一个整型并初始化为10 MyClass *obj = new MyClass(); // 分配MyClass对象并调用构造函 ``` - **构造函**:在类中定义,用于初始化对象。当使用`new`创建对象时,构造函自动调用。 ### 4. Objective-C中的`alloc``init`(引用[1]内容) Objective-C(用于iOS/macOS开发)是C的超集,它使用`alloc``init`来创建初始化对象: - **`alloc`**:类方法,分配内存(类似C的`malloc`),并设置isa指针(指向对象的类)。 - **`init`**:实例方法,用于初始化对象(设置初始状态)。默认的`init`方法可能什么都不做(如引用[1]所示),但子类可以重写。 - **`new`**:相当于`alloc``init`的组合(如引用[1]:`[callAlloc(self, false) init]`)。 ### 5. 总结:C语言、C++Objective-C的对比 | 语言 | 创建(分配内存) | 初始化 | |---------------|------------------------|-------------------------| | **C语言** | `malloc` / `calloc` | 手动赋值或初始化函 | | **C++** | `new` 运算符 | 构造函(自动调用) | | **Objective-C**| `alloc` 类方法 | `init` 实例方法(可重写)| ### 关键区别 - **C语言**:需要分离分配初始化,且初始化完全手动。 - **C++**:`new`将分配初始化(通过构造函)合并为一步。 - **Objective-C**:`alloc`负责分配,`init`负责初始化,通常连用(`[[Class alloc] init]`),而`new`是两者的快捷方式。 ### 注意事项 - 在C语言中,使用`malloc`分配的内存必须用`free`释放,C++中用`delete`,Objective-C中用`release`(在手动引用计下)或自动释放池。 - 初始化在C语言中至关重要,因为未初始化的内存包含随机值,直接使用会导致未定义行为。 ### 示例:C语言中的“创建并初始化”流程 ```c #include <stdlib.h> typedef struct { int id; char name[20]; } Person; // 初始化函(类似init) void init_person(Person *p, int id, const char *name) { p->id = id; strcpy(p->name, name); } int main() { // 分配内存(相当于new的第一步) Person *p = (Person*)malloc(sizeof(Person)); // 初始化(相当于initinit_person(p, 1, "Alice"); // 使用... free(p); // 释放 return 0; } ``` ### 结语 在C语言中,虽然没有内建的`new``init`,但通过`malloc`自定义初始化函可以实现类似功能。理解不同语言中对象创建初始化的机制有助于避免混淆。如果您的问题实际针对C++或Objective-C,请明确语言环境。 §§相关问题§§ 1. C语言中`malloc``calloc`有什么区别? 2. 如何避免C语言中的内存泄漏? 3. C++的构造函析构函有什么作用? 4. Objective-C中`alloc``init`的调用顺序是怎样的? 5. 在C语言中,如何实现类似面向对象的初始化? </think>### C语言中`new`与`init`的区别详解 在C语言中,**`new`不是原生关键字**,而**`init`通常指自定义初始化函**。这与C++或Objective-C的机制不同(引用[1][2])。以下是核心区别--- ### 1. **`new`在C语言中的特殊性** - **非原生支持**: C语言没有内建的`new`运算符(这是C++的特性)。动态内存分配需用`malloc/calloc`: ```c int *arr = (int*)malloc(10 * sizeof(int)); // 类似C++的new int[10] ``` - **功能局限**: `malloc`仅分配**未初始化的内存**(内容随机),需手动初始化(引用[2])。 --- ### 2. **`init`的本质** - **用户定义的函**: `init`是程序员编写的初始化逻辑,非语言关键字: ```c // 自定义初始化函 void init_array(int *arr, int size) { for(int i=0; i<size; i++) arr[i] = 0; } ``` - **职责**: 设置对象初始状态(如清零、赋初值),通常与分配操作分离。 --- ### 3. **关键区别** | 特性 | `new`(实际为`malloc`) | `init`(自定义函) | |--------------|-----------------------------|---------------------------| | **功能** | 分配原始内存 | 初始化内存内容 | | **是否原生** | 需用`malloc`模拟 | 完全由开发者实现 | | **返回值** | 返回未初始化的内存指针 | 无返回值(void) | | **安全性** | 内存内容随机(需手动初始化) | 确保对象处于有效初始状态 | | **调用顺序** | 先于`init`执行 | 在分配内存后调用 | --- ### 4. **典型工作流程** ```c #include <stdlib.h> typedef struct { int id; char name[20]; } Person; // 自定义初始化函init) void init_person(Person *p, int id, const char *name) { p->id = id; strcpy(p->name, name); } int main() { // 分配内存(模拟new) Person *p = (Person*)malloc(sizeof(Person)); // 初始化对象 init_person(p, 1, "Alice"); // 调用初始化逻辑 // 使用对象... free(p); // 释放内存 return 0; } ``` --- ### 5. **与C++/Objective-C的对比** - **C++的`new`**: 同时分配内存+调用构造函(内置初始化能力)[^2]。 - **Objective-C的`init`**: 作为对象方法,用于重置对象状态(引用[1]中`_objc_rootInit`直接返回对象)。 - **C语言的独特性**: 无自动构造/析构机制,需显式分离内存分配(`malloc`)初始化(自定义`init_xxx`函)。 --- ### 总结 C语言中**`new`需用`malloc`模拟**,仅负责分配原始内存;**`init`是开发者设计的初始化函**,负责设置对象有效状态。两者需配合使用: 1. `malloc`分配内存 ➜ 类似`new` 2. 自定义`init`函初始化 ➜ 设置初始值 3. `free`释放内存 ➜ 防止泄漏 这种显式分离提高了灵活性,但也增加了手动管理的复杂度(引用[1][2])。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值