Objective-C:id和void之间的区别*

idvoid *什么区别?

void *表示“对某些随机块或者无types/未知内容的引用”

id意思是“对某个未知类的随机Objective-C对象的引用”

还有其他的语义差异:

  • 在“仅GC”或“GC支持”模式下,编译器将为typesid引用发出写入障碍,但不会为void *types。 在声明结构时,这可能是一个关键的区别。 声明iVars像void *_superPrivateDoNotTouch; 如果_superPrivateDoNotTouch实际上是一个对象,将导致对象过早收割。 不要这样做。

  • 试图调用void *types的引用上的方法将禁止编译器警告。

  • 试图调用idtypes的方法只会在被调用的方法没有在编译器看到的任何@interface声明中声明时才会发出警告。

因此,不应该把一个对象称为void * 。 同样,应该避免使用一个idtypes的variables来引用一个对象。 使用最具体的类types的引用,你可以。 即使NSObject *id好,因为编译器至less可以更好地validation对该引用的方法调用。

void *的一个普通和有效的用法是作为一个不透明的数据引用,通过其他一些API传递。

考虑NSArraysortedArrayUsingFunction: context:方法:

 - (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context; 

sortingfunction将被声明为:

 NSInteger mySortFunc(id left, id right, void *context) { ...; } 

在这种情况下,NSArray只是将作为context参数传入的任何东西作为contextparameter passing给方法。 就NSArray而言,它是一个不透明的指针大小的数据块,你可以自由地将它用于任何你想要的目的。

如果没有语言中的闭包types特征,这是通过函数携带大量数据的唯一方法。 例; 如果您希望mySortFunc()有条件地按照区分大小写或不区分大小写的方式进行sorting,而且仍然是线程安全的,则可以在上下文中传递区分大小写的指示符,可能会在进出的路上投射。

脆弱和容易出错,但只有这样。

块解决这个问题 – 块是closuresC.它们可以在铛 – http://llvm.org/和普遍在雪豹(; http://developer.apple.com/library/ios/documentation/Performance /Reference/GCD_libdispatch_Ref/GCD_libdispatch_Ref.pdf )。

id是一个指向客观C对象的指针,其中void *是指向任何东西的指针。

ID也会closures与调用未知方法有关的警告,例如:

[(id)obj doSomethingWeirdYouveNeverHeardOf];

不会给未知的方法通常的警告。 当然,除非obj没有,或者确实实现了这个方法,否则它会在运行时抛出exception。

通常你应该使用NSObject*id<NSObject>优先于id ,它至less证实返回的对象是一个Cocoa对象,所以你可以放心地使用像retain / release / autorelease这样的方法。

如果一个方法有返回types的id你可以返回任何Objective-C对象。

void手段,该方法不会返回任何东西。

void *只是一个指针。 您将无法编辑指针指向的地址上的内容。

id是一个指向Objective-C对象的指针。 void *是一个指向任何东西的指针。 你可以使用void *而不是id ,但是不推荐使用,因为你永远不会得到编译器的警告。

你可能想看到stackoverflow.com/questions/466777/whats-the-difference-between-declaring-a-variable-id-and-nsobject和unixjunkie.blogspot.com/2008/03/id-vs-nsobject-vs -id.html 。

 /// Represents an instance of a class. struct objc_object { Class isa OBJC_ISA_AVAILABILITY; }; /// A pointer to an instance of a class. typedef struct objc_object *id; 

上面的代码来自objc.h,所以看起来像id是objc_object结构的一个实例,并且isa指针可以与任何Objective C Class对象绑定,而void *只是一个无types的指针。

我的理解是,id代表一个指向对象的指针,而void *可以指向任何东西,只要你把它转换为你想要使用的types

除了已经说过的之外,与集合相关的对象和指针还是有区别的。 例如,如果你想把东西放到NSArray中,你需要一个对象(types为“id”),并且你不能在那里使用一个原始数据指针(types为“void *”)。 您可以使用[NSValue valueWithPointer:rawData]void *rawDdata转换为“id”types以在集合中使用它。 一般而言,“id”更加灵活,并且与附加的对象相关的语义更多。 这里有更多的例子解释Objective C的idtypes 。