What is the difference between id
and void *
?
相关问题
- CALayer - backgroundColor flipped?
- Core Data lightweight migration crashes after App
- back button text does not change
- iOS (objective-c) compression_decode_buffer() retu
- how to find the index position of the ARRAY Where
相关文章
- 现在使用swift开发ios应用好还是swift?
- TCC __TCCAccessRequest_block_invoke
- xcode 4 garbage collection removed?
- Unable to process app at this time due to a genera
- How can I add media attachments to my push notific
- didBeginContact:(SKPhysicsContact *)contact not in
- Custom Marker performance iOS, crash with result “
- Why is my library not able to expand on the CocoaP
In addition to what's already said, there's a difference between objects and pointers related to collections. For example, if you want to put something into NSArray, you need an object (of type "id"), and you can't use a raw data pointer there (of type "void *"). You can use
[NSValue valueWithPointer:rawData]
to convertvoid *rawDdata
to the "id" type for using it inside a collection. In general "id" is more flexible and has more semantics related to objects attached to it. There's more examples explaining id type of Objective C here.id is a pointer to an objective C object, where as void* is a pointer to anything.
id also turns off warnings related to calling unknown mthods, so for example:
[(id)obj doSomethingWeirdYouveNeverHeardOf];
will not give the usual warning about unknown methods. It will, of course, raise an exception at run time unless obj is nil or really does implement that method.
Often you should use
NSObject*
orid<NSObject>
in preference toid
, which at least confirms that the object returned is a Cocoa object, so you can safely use methods like retain/release/autorelease on it.My understanding is that id represents a pointer to an object while void * can point to anything really, as long as you then cast it to the type you want to use it as
If a method has a return type of
id
you may return any Objective-C object.void
means, the method won't return anything.void *
is just a pointer. You won't be able to edit the content on the address the pointer points to.void *
means "a reference to some random chunk o' memory with untyped/unknown contents"id
means "a reference to some random Objective-C object of unknown class"There are additional semantic differences:
Under GC Only or GC Supported modes, the compiler will emit write barriers for references of type
id
, but not for typevoid *
. When declaring structures, this can be a critical difference. Declaring iVars likevoid *_superPrivateDoNotTouch;
will cause premature reaping of objects if_superPrivateDoNotTouch
is actually an object. Don't do that.attempting to invoke a method on a reference of
void *
type will barf up a compiler warning.attempting to invoke a method on an
id
type will only warn if the method being called has not been declared in any of the@interface
declarations seen by the compiler.Thus, one should never refer to an object as a
void *
. Similarly, one should avoid using anid
typed variable to refer to an object. Use the most specific class typed reference you can. EvenNSObject *
is better thanid
because the compiler can, at the least, provide better validation of method invocations against that reference.The one common and valid use of
void *
is as an opaque data reference that is passed through some other API.Consider the
sortedArrayUsingFunction: context:
method ofNSArray
:The sorting function would be declared as:
In this case, the NSArray merely passes whatever you pass in as the
context
argument to the method through as thecontext
argument. It is an opaque hunk of pointer sized data, as far as NSArray is concerned, and you are free to use it for whatever purpose you want.Without a closure type feature in the language, this is the only way to carry along a hunk of data with a function. Example; if you wanted mySortFunc() to conditionally sort as case sensitive or case insensitive, while also still being thread-safe, you would pass the is-case-sensitive indicator in the context, likely casting on the way in and way out.
Fragile and error prone, but the only way.
Blocks solve this -- Blocks are closures for C. They are available in Clang -- http://llvm.org/ and are pervasive in Snow Leopard (http://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/GCD_libdispatch_Ref.pdf).
id
is a pointer to an Objective-C object.void *
is a pointer to anything. You could usevoid *
instead ofid
, but it's not recommended because you'd never get compiler warnings for anything.You may want to see stackoverflow.com/questions/466777/whats-the-difference-between-declaring-a-variable-id-and-nsobject and unixjunkie.blogspot.com/2008/03/id-vs-nsobject-vs-id.html.