What's the difference between void* and id? [duplicate] - iphone

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
objective c difference between id and void *
For example, an UIView animation delegate callback method has this argument:
context:(void*)context
Why not simply id? I always pass nil if I don't care about an context. But when I want one, I pass the object. What's the difference? Why did they prefer void* over id?

id is a pointer to a struct which has isa pointer (which denotes to ObjectiveC runtime that this "thing" is object). void* is simply a pointer to possibly anything (probably another id).

It's to allow you to pass a pointer to anything you like. Can be an obj-c object, a pointer to some array, a struct, whatever. The void * type is just the most general, "anything goes" type.
If you're just passing nil, don't worry about it. You could pass NULL instead if it makes you feel better.

I think you're asking something more than what the difference between id and void* is. It seems you are asking why is it void* in this case.
This is void* because this is your pointer. No one but you will use this. This pointer will not be retained or otherwise used. When the animation calls your callback method it will return this pointer to you untouched. What you do with it depends on what you put in the context: in the first place.
Being a void* lets you do a lot of things. You could pass in a standard objective-c object. You could pass a simple C style data structure. You could pass in a function pointer. You could pass nil and do nothing.

Related

How to get UnsafeRawPointer on the swift object?

My app uses the native C++ lib, there is a method that takes as an argument void*
void foo(void * obj) { ... }
in swift I can call this method like this
func boo(obj: MyCustomObj) {
foo(&obj)
}
and looks like really I get a void pointer on the object, but if I try to get an UnsafeRawPointer on the object like this
func boo(obj: MyCustomObj) {
var pointer = &obj <---- Use of extraneous '&'
foo(pointer)
}
I got an error
Use of extraneous '&'
What is the problem here?
EDIT
I understood that using withUnsafe*** I can get the pointer to the data, but what to do if my method has 2 params, would it looks like this
withUnsafePointer(to: myObjFirst) {
pFirst in
withUnsafePointer(to: myObjSecond) {
pSecond in
foo(pFirst, pSecond)
}
}
The & syntax does not mean "the address of" or "pointer to" like in C. In Swift, it is an in-out expression.
These can be used to create implicit pointer conversions as a convenience, and that can seem like C's "pointer to" meaning, but it has very different rules and behaviors. For example, there is no promise that obj even has an address. It may be a tagged pointer. Passing it via an in-out expression may allocate memory and copy the value to make the call possible. Similarly, when passing a "pointer to an array," Swift will actually pass a pointer to a contiguous block of values (which may have been copied to make them contiguous) which is not the same as the actual Array struct.
It is not meaningful to say var pointer = &obj. There is no in-out reference there.
There is no general way to take long-lived pointers to objects in Swift without allocating your own memory (and this is rare). The memory model doesn't promise the kinds of lifetimes you'd need to make that sensible. If your code did compile the way you expect it to, the call to foo(pointer) would still be invalid because there's no promise that obj exists at that point and the pointer could be dangling. (There are no references to obj after the first line, so Swift can and often will destroy it, even though it's still "in scope.")
The foo(&obj) syntax is basically a shorthand for:
withUnsafePointer(to: obj) { foo($0) }
It exists to make it easier to call C functions, but it doesn't mean that Swift pointers are anything like C pointers.
For much more on Swift pointers, see Safely manage pointers in Swift from WWDC 2020.

confused about Objective-C syntax [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Method Syntax in Objective-C
I just started learning Objective-C and I'm a little confused about this statement.
+(NSMutableArray *) array;
This is what I understand:
+ means this is a method that responds to a class (which makes this a static method)
NSMutableArray is an array that can have it's size change
* pointer ( memory location reference)
array is the name of the array that is of type NSMutableArray.
() Why does this method need parentheses around the object pointer '(NSMutableArray *)'
I don't know how to conceptualize what these part mean as a whole. Can you explain this to me?
in C syntax this would be written as:
static NSMutableArray *array();
NSMutableArray * is the return type. array is the name of the method. There are no arguments, but if there were it would be like this:
+ (ReturnType)methodName:(ArgType)argName;
or if there were multiple arguments:
+ (ReturnType)firstPartOfMethodName:(Arg1Type)arg1Name secondPartOfMethodName:(Arg2Type)arg2Name;
This can be a point of confusion for a lot of Obj-C newcomers. The fact that the method name is split between the arguments can be extremely confusing to most programmers coming from other languages.
The reason that it's ordered that way is to give clarity to the arguments. When using methods like:
- (id)initWithBitmapDataPlanes:(unsigned char **)planes
pixelsWide:(NSInteger)width
pixelsHigh:(NSInteger)height
bitsPerSample:(NSInteger)bps
samplesPerPixel:(NSInteger)spp
hasAlpha:(BOOL)alpha
isPlanar:(BOOL)isPlanar
colorSpaceName:(NSString *)colorSpaceName
bitmapFormat:(NSBitmapFormat)bitmapFormat
bytesPerRow:(NSInteger)rowBytes
bitsPerPixel:(NSInteger)pixelBits
(This is a real method from the Cocoa framework, known for being the longest), it's very helpful that you know which argument to place first, second, third, etc.
The 1,2,3 statements are correct. But fourth one is, array is the name of method. The fifth one is, the return type of array method is NSMutableArray *.
Finally array is the class method and it has NSMutableArray * return type and also does not any arguments.
It look like - (void)viewDidLoad. viewDidLoad is the instance method and it has void return type and also does not any arguments.

Passing a pointer that is part of an object (Cocoa)

OK, I have a custom object (an NSManagedObject subclass, if it matters) and I want to pass a pointer to one of its iVars to a function that I've set up to modify such values. With a normal pointer you'd just prefix it with an ampersand (&) as in the classic NSError &error example, but that can't be done with dot notation. I can't just pass &object.iVar as I'd hoped. Can anyone suggest a simple and elegant way to obtain the pointer of iVar so that I can pass it? I am loath to pass the entire object for reasons of code structure and neatness.
-Ash
Argh, as is almost always the case, I ask a question after an hour of frustrating puzzling then ten minutes later answer it myself. I don't know, maybe asking questions is some kind of therapeutic trigger for answers... shame this isn't a psychology website.
Anyway, my solution was to add a new 'pseudo-getter' method to the object I'm trying to access the pointer from that looks a bit like this:
- (Pointer **)getIVarPointer
{
return &iVar;
}
It's a bit cludgy, but since I only have that one iVar whose pointer I need to obtain it's not too bad. On ther other hand if there is a simpler, more 'official' way of doing this, I'd love to know it!

replaceObjectAtIndex is giving an error, can't figure out why?

So this is the code I have:
[dataCenter.tempPalette replaceObjectAtIndex:9 withObject:selectedColour];
Object 9 does exist, and it's currently an int (not sure if that matters). selectedColour is also an int. dataCenter.tempPalette is a NSMutableArray.
The error it gives me is this:
Passing argument 2 of 'replaceObjectsAtIndex:withObject:' makes pointer from integer without a cast.
Any ideas?
ints aren't objects. If you want to store integers in an NSMutableArray, you'll need to turn them into NSNumbers first using +[NSNumber numberWithInt:]. The error message is complaining that you're passing an int where a pointer (to an object) is required.
The second param of replaceObjectAtIndex needs to be a valid pointer to an object. From your description, it sounds like you are trying to pass in an int value ( selectedColour ), which is not a valid reference to an object.
I believe, instead of passing in the selectedColour int value, you want to pass a reference to the actual color object. This would probably be a reference to a UIColor object.
Also keep in mind, if you are trying to store many objects representing the same color. For purposes of using memory efficiently, you will probably want to store in your tempPallette array references pointing to the same color object for those entries that use the same color.
Hope this helps. Good Luck.

does objective-c methods support "pass by value"?

Does objective-c methods support "pass by value"? Or perhaps to be more specific:
Is the default behavior for parameters passed into a method pass-by-reference?
If yes, are there any variations from this in some circumstances - for example if the parameter is just a basic int as opposed to an object? (or is this not relevant in objective-c)
Is there anyway to have a method support pass-by-value for a basic variable such as int?
Is there anyway to have a method support pass-by-value for an object? (I'm assuming no here, but for completeness will ask. Of course one could within the message do the copy yourself, however for this approach I'll consider this not to be something objective-c methods offers you, i.e. rather it was a do-it-yourself)
thanks
Objective-C does not support references, at least not in the C++ sense of the term.
All Objective-C objects are allocated on the heap, and therefore all "object variables" must in fact be pointer types. Whether a pointer can be considered to be effectively the equivalent of a reference is open to debate. When talking C++ for example, there are clear semantic differences (otherwise, what's the point...)
So to answer your questions:
No, Objective-C only supports pass-by-value. If you pass an object pointer to a method, you pass the pointer by value - you are not passing a reference.
There is no inherent difference between objects and primitives in this regard, apart from the fact that objects are always referred to by pointer, never by value. You can pass a primitive type pointer in if you like.
Yes. This is always the case. Again, if you pass in a pointer to a primitive, you are passing a pointer by value, not a reference.
You're pretty much bang on the mark with this one, other than the fact that you're passing around pointers, not references.
No. It's pass-by-value by default, like in C. Except for the fact that for the Objective C class instance references, the value is a reference. So Objective C class instances are passed effectively by reference.
N/A
See 1.
Not really. You can serialize, pass the string, and recreate inside. Or you can have the object store its ivars as a structure and pass that structure by value. Some objects support cloning.