3

我是 Objective-C 和 ARC 的新手,并且已经搜索和阅读了几个小时而没有找到答案。代码做了我想让它做的事情,但我想知道它不依赖于有利条件。这是我的代码的简化版本:

+(void)foo {
    Class *classes = (__unsafe_unretained Class *)malloc(sizeof(Class) * someValue);

    // Perform work without complicated memory management

    free(classes);
}

我对分配的结构无能为力。它由objc_getClassList填充。不幸的是,Apple 似乎没有更新他们的文档来解释如何在 ARC 下执行此操作。上面的类型转换部分是通过查看示例来构思的,但它仍然让我感到紧张。

我担心的一个问题是,如果我为“常规”对象分配空间,那么dealloc当变量超出范围时就会被调用,这会在free调用之后发生。但我不认为这正是这里发生的事情。

  • 行为是否Class与其他种类的 Objective-C 数据类型不同?我应该期待别的东西吗?
  • 什么样的指针是classes?我猜它引用了一个未知大小的数组(一个非对象指针),但 ARC 仍然关心它,因为没有该强制转换代码将无法编译。它看起来像一个强指针,但我不知道它会是一个强指针。
  • 是否存在指向数组中对象的强指针,或者对象本身是否是强指针?如果没有,ARC 是否仍然有效,或者我应该恢复到某些 MRC 约定?
  • 会有自动呼叫dealloc吗?编译器何时以及如何确保这种情况发生?
  • classes设置为更好的做法NULL,然后才调用到free?或者我应该遍历数组并对每个对象做一些事情,比如将它们设置为nil
4

2 回答 2

2

Class 的行为是否与其他种类的 Objective-C 数据类型不同?我应该期待别的东西吗?

Class是一种可以保存指向任何类对象的指针的类型,就像id可以保存指向任何对象的指针的类型一样,以及NSString *可以保存指向作为实例NSString(或其子类型)的任何对象的指针的类型)。类对象是(一种)对象,其工作方式与其他对象基本相同。该类型Class可以像其他对象指针类型一样使用。

什么样的指针是类?我猜它引用了一个未知大小的数组(一个非对象指针),但 ARC 仍然关心它,因为没有该强制转换代码将无法编译。它看起来像一个强指针,但我不知道它会是一个强指针。

classes是指向的指针Class,即指向类对象的指针。您在这里使用它来指向数组的第一个成员Class,这是正确的。classes不是对象指针,而是指向对象指针的指针;这就是 ARC 关心的原因。就像您将结果转换为malloctoid *NSString **。当您没有在 上指定限定符时Class,它是隐含 __unsafe_unretained的。所以classes已经是一个指向未保留对象指针的指针。

是否存在指向数组中对象的强指针,或者对象本身是否是强指针?如果没有,ARC 是否仍然有效,或者我应该恢复到某些 MRC 约定?

会自动调用dealloc吗?编译器何时以及如何确保这种情况发生?

Class持有指向类对象的指针。类对象基本上是单例;它们没有被引用计数。它们通常在程序的持续时间内存在,除非类被卸载。不需要维护对类对象的显式强引用;班级会留下来。

将类设置为 NULL,然后才调用 free 是否更好?或者我应该遍历数组并对每个对象做一些事情,比如将它们设置为 nil?

您显然不应该在调用 free();之前classes设置为 NULL ;这样,调用不会做任何事情。由于这个数组的元素是,所以在释放内存之前将它们设置为任何东西是没有意义的;它不会有所作为。free(classes);__unsafe_unretained

于 2013-11-19T08:57:27.680 回答
2

您正在分配一个结构指针数组(Class == 指向结构的指针),其中将填充指向注册到运行时的类的指针。只要您的应用程序运行,此指针就不会被释放/释放等。您没有分配任何类,而是分配空间来保存指向此类的指针。你的代码完全没问题,__unsafe_unretained正是你想要的。它告诉 ARC 你持有一个指向你不拥有的对象的指针,因此防止它试图在变量范围的末尾释放它。

于 2013-11-18T12:00:48.970 回答