为什么我们在使用 Quartz API 时必须释放对象?
Why do we have to release objects when using Quartz API?
我最近一直在学习如何在 iOS 开发中使用 Quartz API,并且注意到一些有点奇怪的事情。对于1,为什么我们必须在创建之后释放某些对象?另外,指针变量没有星号,这是为什么呢?像下面的代码:
CGContextRef context = UIGraphicsGetCurrentContext();
在上面的例子中,变量context是一个指针。我们为什么不使用星号?感谢任何 help/guidance。请尽可能详尽,因为我喜欢对我使用的技术有深刻的了解。
您正在处理 C 级 API(未写入或包装在 Objective-C 中)。 CGContextRef
是指向 struct
的指针的 typedef
(C 没有 class,但 structs
是容器类型)。查看 CGContext.h 中 CGContextRef
的定义,您会看到那里使用的星号语法。
我能想到 Apple 定义 CGContextRef
而不是让程序员直接使用指向 CGContext
结构的指针的一个主要原因。在 Objective-C 中,您总是在使用指针。您永远不会使用静态分配的 Objective-C class 实例——事实上,编译器禁止这样做。然而,在 C 中,这不是真的。 Apple 希望将所有对 CGContext
结构的引用保留为指针,以便引用计数按预期工作,并且他们可以保证您使用的对象与他们给您的对象相同。旁注:引用计数本身不是 C 语言的一部分,它是 Apple 写入结构的东西,如 CGContext
允许使用它们进行编程感觉类似于使用 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 分配的内存。
我最近一直在学习如何在 iOS 开发中使用 Quartz API,并且注意到一些有点奇怪的事情。对于1,为什么我们必须在创建之后释放某些对象?另外,指针变量没有星号,这是为什么呢?像下面的代码:
CGContextRef context = UIGraphicsGetCurrentContext();
在上面的例子中,变量context是一个指针。我们为什么不使用星号?感谢任何 help/guidance。请尽可能详尽,因为我喜欢对我使用的技术有深刻的了解。
您正在处理 C 级 API(未写入或包装在 Objective-C 中)。 CGContextRef
是指向 struct
的指针的 typedef
(C 没有 class,但 structs
是容器类型)。查看 CGContext.h 中 CGContextRef
的定义,您会看到那里使用的星号语法。
我能想到 Apple 定义 CGContextRef
而不是让程序员直接使用指向 CGContext
结构的指针的一个主要原因。在 Objective-C 中,您总是在使用指针。您永远不会使用静态分配的 Objective-C class 实例——事实上,编译器禁止这样做。然而,在 C 中,这不是真的。 Apple 希望将所有对 CGContext
结构的引用保留为指针,以便引用计数按预期工作,并且他们可以保证您使用的对象与他们给您的对象相同。旁注:引用计数本身不是 C 语言的一部分,它是 Apple 写入结构的东西,如 CGContext
允许使用它们进行编程感觉类似于使用 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 分配的内存。