pointers - What are difference between *a and **a in objective-c object? -
i write following code:
nsarray *array = @[@1, @2];
how output *array
, **array
, , difference between them?
there answers, think none of them real you, because describe technical meaning. let's have first declaration:
nsarray *array …;
when talks code, find statements array
instance object of nsarray
. every experienced objective-c developer knows real meaning of statement, wrong. correct statement?
a. instance object of nsarray
an instance object has state, set of data stored. so, needs memory, reserved while object creation. not deal directly that, done inside +alloc
. done explicitly @ runtime while program running ("on heap", "heap allocation").
… [nsarray alloc] … // memory instance object of type nsarray
you address such object solely via address, number of first memory cell of occupied memory area. (every memory cell has number, called address. yes, similar addressing inhabitants in house via number of house in street. therefore can imagine memory very, long street.)
but identifier array
exists @ compile time , removed when program compiled. therefore obvious identifier array
never denotes instance object.
short version: instane object area of memory , solely addressed via number of first memory cell (location).
b. pointer instance object (reference)
but if instance object addressed via number @ runtime, how can code deal it? trick number stored in variable. (looking c standard not correct. stored in object. these objects has nothing objective-c objects , focus on variables, subtype of objects.)
so can have variable storing memory location of instance object. such variable called pointer variable. declared *
. so
nsarray * array;
means: pointer variable identifier array
stores location of instance object of type nsarray
.
(addresses numbers. integral numbers. therefore there connection between pointer variables , integers. , can apply calculations numbers, called "pointer arithmetics". in situations important c developers, not objective-c developer.)
the memory variable not reserved explicitly +alloc
, implicitly when enter area of code, variable declared. (not correct again, enough explanation.) let's have again boiled down version of object creation:
- (void)method { nsarray *array = [nsarray alloc]; }
the right side of statement reserved memory object instance , returns number, address of memory area. number assigned reference called array
. memory reference (it stores something, needs memory) reserved implicitly via definition.
pointers objects called references.
short version: array
reference instance object, storing address of instance object.
c. pointer pointer instance object
okay, have instance object occupies memory store object state, addressed via memory location (address). have variable stores address, reference array
. can address via identifier.
but useful – i have example below – address reference variable via address, too. can address of variable using address operator &
.
&array
what is: address of variable storing address of instance object. type of such double indirection ("address of … address of …") is
nsarray ** array;
this is, because in variable definition *
means "address of".
short version: pointer reference variable stores address of variable stores address of instance object. declared **
. (yes, can have more level of indirections … no, not easier understand.)
d. use cases pointers references
usually not need such double indirections in objective-c. there 1 important use case, error out parameter. understand that, @ method single indirected parameter know is:
- (bool)methodthatcanproduceanerror:(nserror*)error { … error = [nserror alloc] … // create error object , store address reference variable error. return no; … }
this method should emit error via error
parameter.
you "call" such method code that:
… nserror *error; // reference variable pointing instance object of type nserror error = nil; // not have error, points "nothing". [aninstance methodthatcanproduceanerror:error];
what happens? pass address of instance object method argument. pass nil
saying "i have no error". quite clear, because method should pass out reference instance object.
so interesting part inside method, when creates error object , tries pass out. this not work!
in objective-c arguments passed value. means, value of argument in "calling code" taken , assigned new variable inside "called code". new variable called parameter variable. when method tries change value of variable
error = [nserror alloc] … // create error object , store address reference variable error.
it solely changes value of variable copy inside method. new reference never find way out of method , variable error
in calling code left untouched. in "calling code", error
still has old nil
value.
so need way change content of reference inside "calling code". passing address of reference method:
- (bool)methodthatcanproduceanerror:(nserror**)error // double indirection { … *error = [nserror alloc] … // *error reference object return no; … }
first in method head declare parameter variable double indirected: address of reference. second assign address of instance object location, error points to. (this done *
.) assignment not done parameter variable, location, parameter variable points to.
therefore can pass address of reference:
nserror *error; // reference variable pointing instance object of type nserror error = nil; // not have error, points "nothing". nserror ** pointertoerror = &error; // address of reference. [aninstance methodthatcanproduceanerror:pointertoerror];
now method changes contents of reference variable. error passed out.
Comments
Post a Comment