What are difference between *a and **a in objective-c object? - objective-c

I write the following code:
NSArray *array = #[#1, #2];
How to output *array and **array, and what is the difference between them?

There are some answers, but I think none of them are a real help to you, because they describe the technical meaning.
Let's have a look to the first declaration:
NSArray *array …;
When somebody talks about this code, you will find statements like array is an instance object of NSArray. Even every experienced Objective-C developer knows the real meaning of this statement, it is simply wrong. What is the correct statement?
A. The instance object of NSArray
An instance object has a state, basically a set of data stored. To do so, it needs memory, which is reserved while object creation. You do not deal directly with that, but it is done inside +alloc. This is done explicitly at runtime while the program is running ("on heap", "heap allocation").
… [NSArray alloc] … // Get memory for an instance object of type NSArray
You address such an object solely via its address, the number of the first memory cell of the occupied memory area. (Every memory cell has a number, called the address. Yes, it is similar to addressing inhabitants in a house via the number of the house in a street. Therefore you can imagine the memory as a very, very long street.)
But an identifier like array only exists at compile time and is removed when the program is compiled. Therefore it is obvious that an identifier like array never denotes an instance object.
Short version: An instane object is an area of memory and is solely addressed via the number of the first memory cell (location).
B. A pointer to an instance object (reference)
But if an instance object is addressed via its number at runtime, how can my code deal with it? The trick is that the number is stored in a variable. (Looking to the C standard that is not completely correct. They say that it is stored in an object. But these objects has nothing to do with Objective-C objects and I will focus on variables, a subtype of objects.)
So you can have a variable storing the memory location of an instance object. Such a variable is called a pointer variable. It is declared with an extra *. So
NSArray * array;
means: A pointer variable with the identifier array that stores the location of an instance object of the type NSArray.
(Addresses are numbers. They are integral numbers. Therefore there is a connection between pointer variables and integers. And you can apply calculations to that numbers, called "pointer arithmetics". In some Situations this is important for C developers, but not for you as an Objective-C developer.)
The memory for this variable is not reserved explicitly with +alloc, but implicitly when you enter the area of your code, where the variable is declared. (Not completely correct again, but enough for this explanation.) So let's have a look again to a very boiled down version of object creation:
- (void)method
{
NSArray *array = [NSArray alloc];
}
The right side of this statement reserved memory for the object instance and returns a number, the address of the memory area. This number is assigned to a reference called array. The memory for that reference (it stores something, so it needs memory) is reserved implicitly via its definition.
Pointers to objects are usually called references.
Short version: So array is a reference to an instance object, storing the address of the instance object.
C. A pointer to a pointer to an instance object
Okay, we have an instance object that occupies memory to store the object state, addressed via its memory location (address). Then we have a variable that stores that address, the reference array. You can address that via its identifier.
But sometimes it is useful – I will have an example below – to address the reference variable via its address, too. You can get the address of a variable using the address operator &.
&array
What you get is: The address of a variable storing the address of an instance object. The type of such a double indirection ("address of … address of …") is
NSArray ** array;
This is, because in a variable definition the * means "address of".
Short version: A pointer to a reference is a variable that stores the address of a variable that stores the address of an instance object. It is declared with **. (Yes, you can have more level of indirections … No, that is not easier to understand.)
D. Use cases for pointers to references
Usually you do not need such double indirections in Objective-C. But there is one important use case, an error out parameter. To understand that, we will look at a method with a single indirected parameter as you know is:
- (BOOL)methodThatCanProduceAnError:(NSError*)error
{
…
error = [NSError alloc] … // Create an error object and store its address to the reference variable error.
return NO;
…
}
This method should emit an error via its error parameter.
You "call" such a method with code like that:
…
NSError *error; // A reference variable pointing to an instance object of type NSError
error = nil; // I do not have an error, so it points to "nothing".
[anInstance methodThatCanProduceAnError:error];
What happens? You pass the address of an instance object to that method as an argument. You pass nil for saying "I have no error". This is quite clear, because the method should pass out a reference to an instance object.
So the interesting part is inside the method, when it creates the error object and tries to pass it out. This does not work!
In Objective-C arguments are always passed by value. That means, that the value of the argument in the "calling code" is taken and assigned to a new variable inside the "called code". This new variable is called a parameter variable. When the method tries to change the value of the variable
error = [NSError alloc] … // Create an error object and store its address to the reference variable error.
it solely changes the value of the variable copy inside the method. The new reference will never find the way out of the method and the variable error in the calling code is left untouched. In the "calling code", error still has its old nil value.
So we need a way to change the content of the reference inside the "calling code". We do that by passing the address of the reference to the method:
- (BOOL)methodThatCanProduceAnError:(NSError**)error // double indirection
{
…
*error = [NSError alloc] … // *error is a reference to an object
return NO;
…
}
First in the method head we declare a parameter variable that is double indirected: The address of a reference. Second we assign the address of an instance object to the location, error points to. (This is done by the *.) The assignment is not done to the parameter variable, but to the location, the parameter variable points to.
Therefore we can pass the address of the reference:
NSError *error; // A reference variable pointing to an instance object of type NSError
error = nil; // I do not have an error, so it points to "nothing".
NSError ** pointerToError = &error; // The address of the reference.
[anInstance methodThatCanProduceAnError:pointerToError];
Now the method changes the contents of the reference variable. The error is passed out.

Related

How to instantiate a pointer in objective-c

Suppose I have a pointer to type ICScannerDevice class for which I have allocated some memory. Now, I want to initialize it with the pointer of type ICDevice which is a parent class of ICScannerDevice.
How do I do this?
Is the following the correct method? I guess not!
ICScannerDevice* scannerDevice = [[ICScannerDevice alloc] init];
scannerDevice = (ICScannerDevice*)device; // device is a pointer to ICDevice.
Suppose I have a pointer to type ICScannerDevice class for which I have allocated some memory.
ICScannerDevice* scannerDevice = [[ICScannerDevice alloc] init];
You are mixing two things up here. Variables are created by declarations, a declaration can also contain an initialisation expression.
When you declare a variable space is allocated which can contain a value of the variable's type - whether that type is int, in which case the value would be a integer e.g. 42, or ICScannerDevice *, in which case that value would be a reference to an allocated ICScannerDevice object.
So the declaration:
ICScannerDevice* scannerDevice
provides all the space you need to store a value of type ICScannerDevice *. The initialisation expression you give:
[[ICScannerDevice alloc] init];
is in your case redundant (and wasteful), you do not wish to create an object of type ICScannerDevice and store a reference to that object in scannerDevice as you wish to store a totally different reference in your variable:
Now, I want to initialize it with the pointer of type ICDevice which is a parent class of ICScannerDevice.
scannerDevice = (ICScannerDevice*)device; // device is a pointer to ICDevice.
This is wrong as you state that device holds a reference to an ICDevice object. As the type ICDevice is a parent of ICScannerDevice a reference to an ICScannerDevice can be treated as one to an ICDevice - aka "upcast".
However a reference known to be an object of type ICDevice may or may not be to an ICScannerDevice it might be , say, to an ICPlotterDevice. So you cannot directly cast - aka "downcast" and assign.
You must first check you actually have a reference to an ICScannerDevice. You do this by checking whether the type of your referenced object, using method isKindOfObject:, is the type ICScannerDevice, and you obtain that type with the class method:
if ( [device isKindOfObject:[ICScannerDevice class]] )
{
// we have a reference to an ICScanner Device
scannerDevice = (ICScannerDevice *)device; // downcast and assign
...
}
else
{
// device references something other than an ICScannerDevice object
// handle this case
...
}
You also need to handle the case where the value stored in device is nil - i.e. it references nothing. You might just want to combine this with the test in the if and treat it as an ICScannerDevice reference:
if ( (device == nil) || [device isKindOfObject:[ICScannerDevice class]] )
or you may need to handle it some other way.
HTH
a pointer is a number that holds a memory address where the object is.
a pointer is(16/32/64 bit) and lives on the stack. just its content is on the heap.
therefore, you don't need to allocate any space for a pointer. Only for the content. Since - in your case - you get a pointer to existing content. Just copy the memory address:
ICScannerDevice* = (ICScannerDevice*)device; // device is a pointer to ICDevice.
NOTE: remember casts don't change the content! if device isn't really a ICScannerDevice but something else, that might crash later.
First, there's no point in allocating an object if you're immediately going to assign some other object to its reference.
Second, if device is not a ICScannerDevice, casting it as one is an error that may or may not cause you problems depending on what you do with it next.
So, the answer is: no, it's not really correct.
(To give you a better answer about what you should be doing instead would require a little more context about where device comes from and how you want to use scannerDevice.)

Are pointers to arguments in Objective C methods are const by default?

There are methods in Cocoa classes that accept an address of a pointer. Most commonly the argument is address of future NSError * object in CoreData validation methods (among others). This way it is possible to put custom or owned object into the place of the address that given argument points to.
My question is: why can't we do that with simple pointer arguments? E.g. let's say I have a method:
- (void)addObject:(id)someObject toArray:(NSMutableArray *)array;
I can easily pass the mutable array as second argument, call addObject: on it and after the method call the array will be modified. Why is this not done with NSError * objects? Are pointers passed to methods are defined as const by default? Is this to avoid accessing NULL?
Why is this not done with NSError * objects?
Because there's no such thing as an NSMutableError. Your example works because you can modify the contents of the array without modifying the pointer to the array itself. However, since NSError instances are immutable, you cannot modify an NSError. As such, you must necessarily create a new error object. And if you want to return that error object along with some other piece of data, at least one of those must be done via an out-parameter (such as an NSError **).
Are pointers passed to methods are defined as const by default?
Nope. Inside that method you're welcome to do this:
- (void)addObject:(id)someObject toArray:(NSMutableArray *)array {
someObject = somethingElse;
[array addObject:someObject];
}
What's important to remember here is that you're only changing a pointer in a slot in memory. The memory slot corresponding to someObject is just a space on the stack, and you're changing the contents of that space to have a value that points to a different allocated object than the one you were given.
Is this to avoid accessing NULL?
Any NULL protection you need must be done yourself.
It's because the NSError class does not define any way to modify instances after creation. The pointer itself is mutable, but an NSError is not.
They are all plain C pointers. They are not const unless you make them const. Const pointers are not a good thing to use in most situations in objective-C, or even often plain C. Const pointers are a subtle concept, and the complexities of the meaning and syntax don't mesh well with the Objective-C style of programming. Forgetting they exist is likely a good first approximation.
Example: NSArray and NSMutableArray - we would not need an NSArray class if const worked 'correctly' - but it can't due to the design of C.
** - For NSError, etc., the idea is to create an NSError, not alter the one you have passed in. In other words, you need a pointer to a pointer to be able to create an instance (i.e. change the actual object).

What is difference between dynamic binding Vs dynamic typing in Objective C

I am having hard time to understand what is difference between dynamic binding Vs dynamic typing in Objective C. Can someone explain this ?
Dynamic typing in Objective-C means that the class of an object of type id is unknown at compile time, and instead is discovered at runtime when a message is sent to the object. For example, in the following code, the class of foo isn't known until we attempt to send the message componentsSeparatedByString:.
id foo = #"One Two Three";
NSArray *a = [foo componentsSeparatedByString:#" "];
If instead of using the id data type we had done the following...
NSString *foo = #"One Two Three";
...then we'd be using static typing rather than dynamic typing.
Dynamic binding means that the compiler doesn't know which method implementation will be selected; instead the method implementation is looked up at runtime when the message is sent. It basically helps us with Polymorphism. So
[foo description]
results in invoking a different method implementation if, for example, foo is an instance of NSArray rather than an instance of NSString.
with dynamic typing you can have a variable of type id that can store any type of object. with dynamic binding you can do this: id obj; [obj doWhatever]; and as long as obj is of a type that implements -(void)doWhatever it will work.
From Apple Documentation
Dynamic typing
A variable is dynamically typed when the type of the object it points to is not checked at compile time. Objective-C uses the id data type to represent a variable that is an object without specifying what sort of object it is. This is referred to as dynamic typing.
Dynamic typing contrasts with static typing, in which the system explicitly identifies the class to which an object belongs at compile time. Static type checking at compile time may ensure stricter data integrity, but in exchange for that integrity, dynamic typing gives your program much greater flexibility. And through object introspection (for example, asking a dynamically typed, anonymous object what its class is), you can still verify the type of an object at runtime and thus validate its suitability for a particular operation.
The following example illustrates dynamic typing using a heterogeneous collection of objects:
NSArray *anArray = [NSArray arrayWithObjects:#"A string", [NSDecimalNumber zero], [NSDate date], nil];
NSInteger index;
for (index = 0; index < 3; index++) {
id anObject = [anArray objectAtIndex:index];
NSLog(#"Object at index %d is %#", index, [anObject description]);
}
The object pointed to by the variable at runtime must be able to respond to whatever messages you send to it; otherwise, your program throws an exception. The actual implementation of the method invoked is determined using dynamic binding.
Dynamic binding
Dynamic binding is determining the method to invoke at runtime instead of at compile time. Dynamic binding is also referred to as late binding. In Objective-C, all methods are resolved dynamically at runtime. The exact code executed is determined by both the method name (the selector) and the receiving object.
Dynamic binding enables polymorphism. For example, consider a collection of objects including Dog, Athlete, and ComputerSimulation. Each object has its own implementation of a run method. In the following code fragment, the actual code that should be executed by the expression [anObject run] is determined at runtime. The runtime system uses the selector for the method run to identify the appropriate method in whatever the class of anObject turns out to be.
NSArray *anArray = [NSArray arrayWithObjects:aDog, anAthlete, aComputerSimulation, nil];
id anObject = [anArray objectAtIndex:(random()/pow(2, 31)*3)];
[anObject run];
If you are familiar with Javascript, dynamic typing in objective C is pretty much similar to what 'var' is in Javascript, where the actual type of this variable will be figured out at run-time and once it's assigned. It can be reused and retyped as many times as you like which makes it risky to use if you don't know the type of the object being held at the time of the execution as you as it could through 'unrecognized selector' run time exceptions. In Objective-C, all objects are of type id and therefore a variable of type id can be used for dynamic typing.
Dynamic Binding on objects is the 'polymorphic' behavior where the right method is called based on the type of object it's being called on at run time.
I hope that helps

Assigning object pointers

Is this pointer assignment correct?
customclass.somearray = &*otherarray;
where somearray and otherarray are NSArray objects.
If not, how do I solve my problem:
I want to share this otherarray object with customclass.somearray. And I want all changes
made to customclass.somearray to be made to the original otherarray too.
Doing it this way, it works. I just want to ask, is it correct?
Your two variables are pointers of the same type, so just assign one to the other:
customclass.somearray = otherarray;
The way you have written this is unnecessary. Using the dereference operator * essentially gives you the "contents" of the pointer. The address-of operator & correspondingly gives you the address of whatever you apply it to. Your pointer otherarray contains an address. If you dereference that address and then take the address of that, you end up right back where you started.
Be aware that the left side of this assignment is a property access (assuming that customclass is also an object and not just a struct). This means that the compiler will change your expression into:
[customclass setSomearray:&*otherarray];
// And my version will be changed into:
[customclass setSomearray:otherarray];
That is, it becomes a method call rather than a simple assignment. This does not affect the syntax you should use, however.
When working in Objective-C, you never deal with objects directly, but always refer to them via pointers. Always. In C++, you can declare an actual object on the stack, for example, but you never do that in Objective-C. So, if you have:
NSArray *otherArray = [NSArray arrayWithObjects:#"foo", #"bar", nil];
then otherArray is a pointer to an instance of NSArray. Likewise, your somearray property will be of type NSArray*, so the types will match and you can just assign one to the other:
customclass.somearray = otherarray;
Hope that helps.

Instance pointers in an array

I'm trying to save pointers of class instances into a mutable array. I'm able to do this but getting them back into use seems to be a problem. The next is how I inserted the pointers into the array:
Class *class = [Class new];
/* Do something with the instance */
[instanceArray addObject:class];
I am able to retrieve the wanted index from the array but when I try to access the instance variables etc. I only get compiler shouting at me or sometimes I get every variable as zero.
How am I supposed to get the instance back to use from the array? I know they are pointers but playing with them didn't seem to work.
Using addObject: the element is inserted at the end of the array. To retrieve it you can use -[NSArray objectAtIndex:]
Pointer arithmetic works in C since then your array is just a pointer to the first index, and array[i] is the same as *(array + i). In Objective-C this may still be done, however you're using an NSArray object. Now you don't have a pointer to the first object anymore, but to the instance of the class. To retrieve the objects stored in the array, you'll have to call the corresponding methods.
EDIT
So you are able to retrieve it from the array and then your pointer is not nil, so you do have access to the object. You know in Objective-C, all instance variables are private so you can't access them from outside. You'd have to declare them as properties first (please refer to the documentation). Also, when you declare a variable to be of type id, accessing a property with dot-syntax doesn't work, it will cause a compiler error.