返回

从“iOS-alloc & init & new”探寻OC内存管理之谜

IOS

问题先行:

  1. 如上代码中,p1、p2、p是否一样?
  2. 如上代码第一行控制台输出结果是什么?
  3. 如上代码中,p1、p2和p3、p4是否一样?
  4. 如上代码后三行控制台输出是什么样子的?
  5. 字节对齐算法是什么?

深入探讨“alloc & init & new”:

在iOS开发中,我们经常会遇到“alloc & init & new”这三个关键词。它们都是用于创建对象,但用法和区别却大不相同。

  1. alloc:

    alloc方法用于分配内存空间,为对象创建一个实例。但是,此时对象还没有被初始化,它的属性值都是未定义的。

    语法:

    id alloc()
    

    返回值:

    一个指向新创建的对象的指针。

  2. init:

    init方法用于初始化对象,为对象的属性赋值。

    语法:

    id init()
    

    返回值:

    一个指向已初始化的对象的指针。

  3. new:

    new方法与alloc方法类似,用于分配内存空间,为对象创建一个实例。但是,new方法会自动调用init方法,完成对象的初始化。

    语法:

    id new()
    

    返回值:

    一个指向已初始化的对象的指针。

对比“alloc & init & new”:

特性 alloc init new
内存分配
对象初始化
返回值 指向未初始化对象的指针 指向已初始化对象的指针 指向已初始化对象的指针

字节对齐算法:

字节对齐算法是一种内存管理技术,它可以确保对象在内存中以特定字节边界对齐。这对于提高内存访问效率和性能非常重要。

在iOS中,字节对齐算法默认情况下是启用的。我们可以通过以下方式来查看字节对齐算法是否启用:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // 创建一个结构体对象
        struct MyStruct {
            int a;
            char b;
            double c;
        } myStruct;
        
        // 打印结构体对象的大小
        NSLog(@"Size of MyStruct: %lu", sizeof(myStruct));
    }
    return 0;
}

运行这段代码,控制台会输出:

Size of MyStruct: 24

这意味着MyStruct结构体的大小为24字节。但是,如果我们禁用字节对齐算法,MyStruct结构体的大小将变为12字节。

我们可以通过以下方式来禁用字节对齐算法:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // 创建一个结构体对象
        struct MyStruct {
            int a;
            char b;
            double c;
        } __attribute__((packed)) myStruct;
        
        // 打印结构体对象的大小
        NSLog(@"Size of MyStruct: %lu", sizeof(myStruct));
    }
    return 0;
}

运行这段代码,控制台会输出:

Size of MyStruct: 12

这意味着MyStruct结构体的大小变为了12字节。

字节对齐算法的优点:

  • 提高内存访问效率和性能。
  • 减少内存碎片。
  • 使得代码更加健壮。

字节对齐算法的缺点:

  • 可能会增加内存使用量。
  • 可能会降低代码的可读性。

结论:

“alloc & init & new”是iOS开发中用于创建对象的三个关键词。它们用法和区别各不相同,开发者需要根据具体情况选择使用哪一个。字节对齐算法是一种内存管理技术,它可以确保对象在内存中以特定字节边界对齐。这对于提高内存访问效率和性能非常重要。