Objective-C:id和void之间的区别*
id和void *什么区别?
void *表示“对某些随机块或者无types/未知内容的引用”
id意思是“对某个未知类的随机Objective-C对象的引用”
还有其他的语义差异:
-
在“仅GC”或“GC支持”模式下,编译器将为types
id引用发出写入障碍,但不会为void *types。 在声明结构时,这可能是一个关键的区别。 声明iVars像void *_superPrivateDoNotTouch;如果_superPrivateDoNotTouch实际上是一个对象,将导致对象过早收割。 不要这样做。 -
试图调用
void *types的引用上的方法将禁止编译器警告。 -
试图调用
idtypes的方法只会在被调用的方法没有在编译器看到的任何@interface声明中声明时才会发出警告。
因此,不应该把一个对象称为void * 。 同样,应该避免使用一个idtypes的variables来引用一个对象。 使用最具体的类types的引用,你可以。 即使NSObject *比id好,因为编译器至less可以更好地validation对该引用的方法调用。
void *的一个普通和有效的用法是作为一个不透明的数据引用,通过其他一些API传递。
考虑NSArray的sortedArrayUsingFunction: 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 。