代码之家  ›  专栏  ›  技术社区  ›  Vimzy

为什么在使用Quartz API时必须释放对象?

  •  0
  • Vimzy  · 技术社区  · 10 年前

    我最近一直在学习如何在iOS开发中使用Quartz API,并注意到一些有点奇怪的事情。对于1,为什么我们必须在制作某些对象后释放它们?此外,指针变量没有星号,这是为什么?如以下代码所示:

    CGContextRef context = UIGraphicsGetCurrentContext();
    

    在上面的示例中,变量上下文是一个指针。为什么不使用星号?感谢任何帮助/指导。请尽可能彻底,因为我喜欢对我使用的技术有深刻的了解。

    1 回复  |  直到 10 年前
        1
  •  1
  •   Mathew    10 年前

    您正在处理一个C级API(不是用Objective-C编写或包装的)。 CGContextRef 是一个 typedef 指向 struct (C没有类,但 structs 是容器类型)。看看 CGContextRef 在里面 CGContext.h 您将看到此处使用的星号语法。

    有一个主要原因我能想到为什么苹果会定义 CGContextRef 而不是让程序员使用指向 CGContext 直接构造。在Objective-C中,您总是使用指针。您从未使用静态分配的Objective-C类实例——事实上,编译器禁止这样做。然而,在C语言中,这是不正确的。苹果希望保留所有引用 图形上下文 结构作为指针,以便引用计数按预期工作,并且它们可以保证您使用的对象与它们给您的对象相同。附带说明:引用计数本身不是C语言的一部分,它是苹果公司编写的结构 图形上下文 以使使用它们的编程感觉类似于使用Objective-C对象的编程。考虑以下代码片段作为我所谈论内容的简要示例。

    在C语言中(您可以将其编译为Objective-C程序的一部分):

    typedef struct {int a; int b; int refCount;} SimpleObject;
    
    SimpleObject *obj1 = malloc(sizeof(SimpleObject));
    obj1->a = 5;
    obj1->b = 6;
    obj1->refCount = 1;
    
    SimpleObject *obj2 = obj1;
    
    NSLog(@"test: (%d, %d) (%d, %d) (%d, %d)", obj1->a, obj2->a, obj1->b, obj2->b, obj1->refCount, obj2->refCount);
    NSLog(@"test: %d", obj1 == obj2); //they are literally the same object (same location in memory)
    
    SimpleObject obj3 = *obj1;
    
    NSLog(@"test: (%d, %d) (%d, %d) (%d, %d)", obj1->a, obj3.a, obj1->b, obj3.b, obj1->refCount, obj3.refCount);
    NSLog(@"test: %d", obj1 == &obj3); //they are not the same object (same location in memory)
    
    obj1->refCount--;
    
    NSLog(@"test: how many retains on obj1? %d  how about obj2? %d  and obj3? %d", obj1->refCount, obj2->refCount, obj3.refCount);
    
    free(obj1);
    

    在Objective-C中尝试类似的方法,编译器很快就会抛出错误:

    NSObject *obj1 = [[NSObject alloc] init];
    
    NSObject *obj2 = obj1;
    
    NSLog(@"test: %d", obj1 == obj2); // they are literally the same object (same location in memory)
    
    NSObject obj3 = obj1; // compiler error
    

    自动引用计数(ARC)允许您在Objective-C中分配内存,然后不用担心稍后释放或释放内存。这是一个编译器特性,仅对Obj-C对象进行操作,因此必须显式释放此和其他C级API分配的内存。

    推荐文章