Understanding self in Objective-C - objective-c

The code below is from an iTunes U course on iPhone dev in Objective-C. I've read the Apple documentation and it's all very very clear with the exception of self. I sort of understand self to be a pointer to myself, but what exactly does that mean? In the code below what exactly does self mean? What is the difference between self.topSpeed and self.nearestWormhole in the implementation file or does self refer to the same thing on both occasions? Does self.topSpeed refer to Planet * and self.nearestWormhole refer to Wormhole * ? Thanks to anyone who answers, I've learned C and now trying to learn OOP so any input is appreciated.
(Header file)
#import "Vehicle.h"
#import "Planet.h"
#interface Spaceship : Vehicle
#property (nonatomic) double topSpeed;
- (void)orbitPlanet:(Planet *)aPlanet
atAltitude:(double)km;
#end
(Implementation file)
#import "Spaceship.h"
#interface Spaceship()
#property (nonatomic, strong) Wormhole *nearestWormhole;
#end
#implementation Spaceship
#synthesize topSpeed = _topSpeed;
#synthesize nearestWormhole = _nearestWormhole;
- (void)setTopSpeed:(double)speed
{
if ((speed < 1) && (speed > 0)) _topSpeed = speed;
}
- (void)orbitPlanet:(Planet *)aPlanet atAltitude:(double)km
{
double speed = self.topSpeed;
if (speed > MAX_RELATIVE) speed = MAX_RELATIVE;
[self.nearestWormhole travelToPlanet:aPlanet
atSpeed:speed];
}
#end

self (or this in C++) refers to the object which is executing the method (or "on which the method is being invoked").
Suppose I have a room with three people, Arthur, Betty, and Ziggy, and a box of hats. We also define that
Arthur's teacher is Betty.
Betty's teacher is Ziggy.
Ziggy does not have a teacher.
I want to give the following set of instructions to all three people:
1. Put a hat on Ziggy's head.
This is pretty easy. "Ziggy" means the same person to Arthur, Betty, and even Ziggy. No matter who follows this instruction the same person receives the hat.
2. Put a hat on the head of your teacher, if you have one.
This instruction will have a different effect depending on who's following it, because teacher refers to someone different for each of the three. But each can ask him/herself "who is my teacher, if I have one?" and find that person.
But the next thing I want is for Arthur to put a hat on Arthur's head, Betty to put a hat on Betty's head, and Ziggy to put a hat on Ziggy's head. We can't refer to that person by name (like Ziggy) because it depends on who is doing it. Suppose we treat it like "teacher" and establish a variable "foo" such that Arthur's foo is Arthur, and Betty's foo is Betty… but it should be obvious that the idea we are really expressing is that Ziggy's foo is Ziggy, and Jack's foo would be Jack, and Skip's foo would be Skip… do we really need to establish a "foo"? No! Everyone has a foo: it's your self. So let's define an implicit variable "self" that is not declared anywhere but always refers to the person carrying out the action.
3. Put a hat on the head of your self.
This works for Arthur, Betty, Ziggy, and even Jack. It works for anyone.
In your code self refers to the Spaceship whose topSpeed needs to be accessed. You create many Spaceships and each needs to know the topSpeed of that one Spaceship which exists (we know it does because it's calling the method) but has no name (like myWingman.topSpeed) - one's self.

Cristian, I'll offer you a different tack on this. You say you know C, let's start there. If you needed to implement fractions you'd use a struct, and let's assume for some reason you decide to dynamically allocate your fractions. You have something like this:
typedef struct { int numerator; int denominator; } Fraction;
Fraction *newFraction(int numer, int denom)
{
Fraction *result = (Fraction *)malloc(sizeof(Fraction)); // allocate
result->numerator = numer;
result->denominator = denom;
return result;
}
Fraction *multiplyFraction(Fraction *left, Fraction *right)
{
Fraction *result = (Fraction *)malloc(sizeof(Fraction)); // allocate
result->numerator = left->numerator * right->numerator; // multiple (ignoring reduction)
result->denominator = left->denominator * right->denominator;
return result;
}
And you'd use it like:
Fraction *half = newFraction(1, 2);
Fraction *twothirds = newFraction(2, 3);
Fraction *onethird = multiplyFraction(half, twothirds); // results is 2/6 as we don't reduce in this example
This is the ADT - abstract data type - style of programming. You declare a data type whose content is private (the "abstract" part) to the functions you will provide, and a bunch of functions.
At the basic level what object-oriented programming does is just invert the way you look at this. Instead of "call function multiplyFraction passing two fractions" you say "pass the message multiplyFraction, along with a fraction, to a fraction". Using Objective-C syntax the last line above:
Fraction *onethird = multiplyFraction(half, twothirds);
becomes:
Fraction *onethird = [half multiplyFraction:twothirds];
Under the hood this "method send" just becomes a "function call" - Objective-C does a bit of work to locate multipleFraction and then calls it passing it both half and twoThirds.
Almost there! Now to match the changed syntax for the call Objective-C also changes the syntax of the definition of multiplyFraction:
- (Fraction *) multiplyFraction:(Fraction *)right
{
Fraction *result = [Fraction new]; // allocate
result->numerator = ????->numerator * right->numerator;
result->denominator = ????->denominator * right->denominator;
return result;
}
But what do you write for ????. As you'll see the syntax only names the second parameter (right), there is no name given for the first (which was left). Objective-C hides the passing of this parameter, every method takes at least one parameter - it is the "object" (rather than "ADT") that the method is sent to. It needs a name so you can refer to it, that name is self:
- (Fraction *) multiplyFraction:(Fraction *)right
{
Fraction *result = [Fraction new]; // allocate
result->numerator = self->numerator * right->numerator;
result->denominator = self->denominator * right->denominator;
return result;
}
And this is essentially it - self is the name of the first argument.
Object-oriented languages build upon this base, for example:
they had direct access to "instance" variables - the "fields" of the original struct;
they change some more syntax - e.g. #interface... replaces struct...; and rather than list the methods (functions) after the type (struct) in the header they are listed inside of it (the `#interface);
they usually add inheritance (though some ADT languages have that as well);
etc.
But under the hood an Objective-C class is implemented as a C struct...
HTH

Objective C emphasizes using getters and setters. To make things simpler, it even generates getters and setters when you #synthesize something.
So
self.topSpeed
accesses the getter for topSpeed. If you omit the "self" part, then it is equivalent to accessing the instance variable(ivars) directly (bad practice).
The reason for having a underscore before the variable name is also to make a clear differentiation between instance variable and the getter for the instance variable. This way, we cannot accidentally refer to topSpeed without "self".
You need to use self to access variable in all places except:
init
dealloc
Hope that helps.

self is indeed a pointer reference to the instance of the class that is running the code. In this case, self would be a reference to an instance of the Spaceship class.
When you reference self in a class method (which is very possible and an acceptable behavior), you are actually referencing a singleton instance representing the class. You can also get this singleton instance by calling [Spaceship class]. In practice, you'd use self like this mostly in factory methods when you need to allocate a new instance.
What you seem more confused about is syntax regarding other classes. You asked:
Does self.topSpeed refer to Planet * and self.nearestWormhole refer to
Wormhole * ?
Wormhole *nearestWormhole represents an instance of the Wormhole class, named nearestWormhole. So, when you use self.nearestWormhole, that is a pointer to a instance of the Workhole class. Inside the Spaceship class you could actually use _nearestWormhole or self.nearestWormhole to access that pointer. Other classes might call something like spaceship.nearestWormhole, which is using the accessor.

'self' refers to the instance of the current class, i.e. in your example it would refer to an instance of the Spaceship class. Because 'self' always refers to an instance of the class, it's not possible to call upon self in class methods.

Related

Objective C Instance Method Help *Beginner*

Can you guys help me understand a concept real quick, I'm having trouble understanding the conversion from C to objective-C:
If I had a particular instance method that look like this:
-(void)addOwnerNamesObject:(NSString *)n;
{
// ownerNames defined as NSMutableSet
[ownerNames addObject:n];
}
I understand a few things...
It is an instance method that can be called by the program.
In C this would not return anything (just execute the code in the curlies)
In C, the syntax is slightly less confusing - (void)InstanceMethod(Char *nameOfArgument)
Here's where I need help:
When you call this method are you still sending it an argument?
If so, is that argument an NSString instance that the method names n?
And finally... off topic
If you have a method...
-(id)someMethod:(NSString *)pn
{
}
What is the (id) for? does that tell the compiler that it can return any type of object?
Thanks for helping the Newbie... Much appreciated.
First of all, you should really take a look at the basic Objective-C documentation.
In Objective-C, a method can be preceded by a + or - sign.
+ is for class methods, - is for instance methods.
Then you have the return type, inside parenthesis, and the method name.
- ( int )foo;
An instance method named foo, returning an int.
A similar C function would be:
int foo( void );
In Objective-C, the method name is a bit special when you have arguments.
For instance:
- ( int )foo: ( double )num;
A member method named foo:, returning an int and taking a double argument named num.
Similar C function:
int foo( double num );
Now with multiple arguments:
- ( int )foo: ( double )num1 bar: ( float )num2;
A member method named foo:bar:, returning an int and taking a double argument named num1 and a float argument named num2.
Similar C function:
int foo( double num1, float num2 );
About your question on id, it's simply the method return type.
id is a typedef used for Objective-C instances.
Basically, it's a void *.
id does represent an Objective-C object pointer, for any class.
You already know what you're talking about.
1.) When you call this method are you still sending it an argument?
yes, whatever is after the colon
add multiple colons to pass additional parameters...
-(void)addOwnerNamesObject:(NSString *)n withSomeIntYouWantToPass:(int)value;
2.) If so, is that argument an NSString instance that the method names 'n'?
yes
3.) What is the (id) for? Does that tell the compiler that it can return any type of object?
yes, you will return an NSObject or subclass of NSObject
First the dash (-) in the method name says that this is an instance method which means you need an instance to send this message to. The call would look something like this:
NSString* s = #"a string";
[someInstance addOwnersNameObject:s];
In this case you are passing the NSString instance s to the addOwnersNameObject message.
id is like void * in C.
To add to those very valid answers already given with a further discussion of id:
Objects in Objective-C are typeless, which means that at a fundamental level you don't need to know the type to be able to talk to the object. That's one of the big differences between Objective-C and, say, C++.
Pointers to objects are usually typed, such as NSString * to make the code more readable and to indicate your intentions to the compiler so that it can provide suitable warnings if you do anything odd.
id is a typeless pointer to an object. Any object type can be passed as id and any id value can be assigned to any object pointer without casting.
99.99% of the time, id could be replaced with NSObject * since 99.99% of objects inherit from NSObject, meaning that you could use the fact of inheritance rather than the fact of typeless objects to pass things around generically. However NSObject is a little bit special in being both an object and a protocol and some objects aren't actually subclasses of NSObject — NSProxy and the classes that represent blocks jump immediately to mind. You'll rarely be particularly interested in those special cases but id is nevertheless often used as a convention because people prefer the semantics of passing an object with no indication of its type to passing an object with a known ancestor.

Would it be beneficial to begin using instancetype instead of id?

Clang adds a keyword instancetype that, as far as I can see, replaces id as a return type in -alloc and init.
Is there a benefit to using instancetype instead of id?
Yes, there are benefits to using instancetype in all cases where it applies. I'll explain in more detail, but let me start with this bold statement: Use instancetype whenever it's appropriate, which is whenever a class returns an instance of that same class.
In fact, here's what Apple now says on the subject:
In your code, replace occurrences of id as a return value with instancetype where appropriate. This is typically the case for init methods and class factory methods. Even though the compiler automatically converts methods that begin with “alloc,” “init,” or “new” and have a return type of id to return instancetype, it doesn’t convert other methods. Objective-C convention is to write instancetype explicitly for all methods.
Emphasis mine. Source: Adopting Modern Objective-C
With that out of the way, let's move on and explain why it's a good idea.
First, some definitions:
#interface Foo:NSObject
- (id)initWithBar:(NSInteger)bar; // initializer
+ (id)fooWithBar:(NSInteger)bar; // class factory
#end
For a class factory, you should always use instancetype. The compiler does not automatically convert id to instancetype. That id is a generic object. But if you make it an instancetype the compiler knows what type of object the method returns.
This is not an academic problem. For instance, [[NSFileHandle fileHandleWithStandardOutput] writeData:formattedData] will generate an error on Mac OS X (only) Multiple methods named 'writeData:' found with mismatched result, parameter type or attributes. The reason is that both NSFileHandle and NSURLHandle provide a writeData:. Since [NSFileHandle fileHandleWithStandardOutput] returns an id, the compiler is not certain what class writeData: is being called on.
You need to work around this, using either:
[(NSFileHandle *)[NSFileHandle fileHandleWithStandardOutput] writeData:formattedData];
or:
NSFileHandle *fileHandle = [NSFileHandle fileHandleWithStandardOutput];
[fileHandle writeData:formattedData];
Of course, the better solution is to declare fileHandleWithStandardOutput as returning an instancetype. Then the cast or assignment isn't necessary.
(Note that on iOS, this example won't produce an error as only NSFileHandle provides a writeData: there. Other examples exist, such as length, which returns a CGFloat from UILayoutSupport but a NSUInteger from NSString.)
Note: Since I wrote this, the macOS headers have been modified to return a NSFileHandle instead of an id.
For initializers, it's more complicated. When you type this:
- (id)initWithBar:(NSInteger)bar
…the compiler will pretend you typed this instead:
- (instancetype)initWithBar:(NSInteger)bar
This was necessary for ARC. This is described in Clang Language Extensions Related result types. This is why people will tell you it isn't necessary to use instancetype, though I contend you should. The rest of this answer deals with this.
There's three advantages:
Explicit. Your code is doing what it says, rather than something else.
Pattern. You're building good habits for times it does matter, which do exist.
Consistency. You've established some consistency to your code, which makes it more readable.
Explicit
It's true that there's no technical benefit to returning instancetype from an init. But this is because the compiler automatically converts the id to instancetype. You are relying on this quirk; while you're writing that the init returns an id, the compiler is interpreting it as if it returns an instancetype.
These are equivalent to the compiler:
- (id)initWithBar:(NSInteger)bar;
- (instancetype)initWithBar:(NSInteger)bar;
These are not equivalent to your eyes. At best, you will learn to ignore the difference and skim over it. This is not something you should learn to ignore.
Pattern
While there's no difference with init and other methods, there is a difference as soon as you define a class factory.
These two are not equivalent:
+ (id)fooWithBar:(NSInteger)bar;
+ (instancetype)fooWithBar:(NSInteger)bar;
You want the second form. If you are used to typing instancetype as the return type of a constructor, you'll get it right every time.
Consistency
Finally, imagine if you put it all together: you want an init function and also a class factory.
If you use id for init, you end up with code like this:
- (id)initWithBar:(NSInteger)bar;
+ (instancetype)fooWithBar:(NSInteger)bar;
But if you use instancetype, you get this:
- (instancetype)initWithBar:(NSInteger)bar;
+ (instancetype)fooWithBar:(NSInteger)bar;
It's more consistent and more readable. They return the same thing, and now that's obvious.
Conclusion
Unless you're intentionally writing code for old compilers, you should use instancetype when appropriate.
You should hesitate before writing a message that returns id. Ask yourself: Is this returning an instance of this class? If so, it's an instancetype.
There are certainly cases where you need to return id, but you'll probably use instancetype much more frequently.
There definitely is a benefit. When you use 'id', you get essentially no type checking at all. With instancetype, the compiler and IDE know what type of thing is being returned, and can check your code better and autocomplete better.
Only use it where it makes sense of course (i.e. a method that is returning an instance of that class); id is still useful.
Above answers are more than enough to explain this question. I would just like to add an example for the readers to understand it in terms of coding.
ClassA
#interface ClassA : NSObject
- (id)methodA;
- (instancetype)methodB;
#end
Class B
#interface ClassB : NSObject
- (id)methodX;
#end
TestViewController.m
#import "ClassA.h"
#import "ClassB.h"
- (void)viewDidLoad {
[[[[ClassA alloc] init] methodA] methodX]; //This will NOT generate a compiler warning or error because the return type for methodA is id. Eventually this will generate exception at runtime
[[[[ClassA alloc] init] methodB] methodX]; //This will generate a compiler error saying "No visible #interface ClassA declares selector methodX" because the methodB returns instanceType i.e. the type of the receiver
}
You also can get detail at The Designated Initializer
**
INSTANCETYPE
**
This keyword can only be used for return type, that it matches with return type of receiver. init method always declared to return instancetype.
Why not make the return type Party for party instance, for example?
That would cause a problem if the Party class was ever subclassed. The subclass would inherit all of the methods from Party, including initializer and its return type. If an instance of the subclass was sent this initializer message, that would be return? Not a pointer to a Party instance, but a pointer to an instance of subclass. You might think that is No problem, I will override the initializer in the subclass to change the return type. But in Objective-C, you cannot have two methods with the same selector and different return types (or arguments). By specifying that an initialization method return "an instance of the receiving object," you would never have to worry what happens in this situation.
**
ID
**
Before the instancetype has been introduced in Objective-C, initializers return id (eye-dee). This type is defined as "a pointer to any object". (id is a lot like void * in C.) As of this writing, XCode class templates still use id as the return type of initializers added in boilerplate code.
Unlike instancetype, id can be used as more than just a return type. You can declare variables or method parameters of type id when you are unsure what type of object the variable will end up pointing to.
You can use id when using fast enumeration to iterate over an array of multiple or unknow types of objects. Note that because id is undefined as "a pointer to any object," you do not include an * when declaring a variable or object parameter of this type.
The special type instancetype indicates that the return type from the init method will be the same class as the type of object it is initializing (that is, the receiver of the init message). This is an aid for the compiler so that it can check your program and flag potential
type mismatches—it determines the class of the returned object based on context; that is, if you’re sending the init message to a newly alloc’ed Fraction object, the compiler will infer that the value returned from that init method (whose return type has been declared as type instancetype) will be a Fraction object. In the past the return type from an initialization method was declared as type id. This new type makes more sense when you consider subclassing, as the inherited initialization methods cannot explicitly define the type of object they will return.
Initializing Objects, Stephen G. Kochan, Programming in Objective-C, 6th Edition

(Objective C) what is the advantage of doing #synthesize myvar = _myvar (if any)? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How does an underscore in front of a variable in a cocoa objective-c class work?
It is not fully clear to me (other than for readability of the code), why you wanna create an internal variable with an underscore prefix when you create the property.
Since everything is handled internally, why bother to do so, since we do not add any code to the getter and setter?
And even if i gotta add some code to the getter or setter, i do not see why i cannot just do the check on myvar instead than having to check _myvar and then assign it to myvar.
Can anyone give me some explanation, other than "do it because that's what everyone does ?" I would like to understand the whole reason behind this practice (that seems to be pretty common even if there is no custom code for the getter and setter).
Thanks!
I've wondered this many times myself. Interested in other people's answer, but one reason I've found is that it forces you to notice if you're accessing the ivar directly when you should be using the getter/setter.
self.myvar = #"blah"; and _myvar = #"blah";
vs
self.myvar = #"blah"; and myvar = #"blah";
It's easy to leave the self. out by accident... it's a lot harder to put the _ in by accident.
An Objective-C property usually has a backing instance variable (I guess you know the difference between a property and an instance variable).
The property may have a different name than the instance variable.
For instance, you may have an instance variable named x, with a property named y.
You can synthesize the y property to the x variable using:
#synthesize y = x;
Now about the underscore.
It's a common practice to use an underscore prefix for instance variables, to prevent naming collisions, or compiler warnings (shadowed variable), when having for instance a method argument with the same name as an instance variable.
The underscore prefix also makes clear that you are referring to an instance variable.
By using the underscore prefix for instance variables, you're free to use the name without the underscore in method's arguments, stack variables, etc.
But when using a property, you usually don't want the user to write an underscore.
So you usually have an x property for an _x instance variable.
This is why you write:
#synthesize x = _x;
Let's take an example:
#interface Test: NSObject
{
int x;
}
#property( readonly ) int x;
#end
This is quite common... But now imagine this in the implementation:
- ( id )initWithX: ( int )x
{}
We have are a naming collision.
Inside our method, x will refer to the method's argument. And there is no pretty way to access the x instance variable.
Depending on your compiler's warning flags, this may also generate a warning (-Wshadow).
If you use an underscore prefix for your instance variable, everything is just simple:
- ( id )initWithX: ( int )x
{
if( ( self = [ super init ] ) )
{
_x = x;
}
return self;
}
No conflict, no naming collision, improved reading... Just a nice way...
When using a property of self, it's easy to forget the "self":
[self.field doSomething]; // what you probably want
[self setField:someObject]; // also kosher
self.field = someObject; // ditto, although not my style
vs.
[field doSomething] // might work.. but will bite you eventually
field = someObject; // almost certainly wrong anywhere outside a custom setter
If the property and the ivar are named identically, the latter cases will compile without complaint and appear to work... until they don't, and you get a weird hard-to-reproduce edge case bug.
If the ivar has a slightly different name, say with a trailing _ appended, the compiler will stop you and make you explicitly decide: do I want to refer to the property here, or the ivar directly?
(All that said, I am lazy and often do #synthesize field;, and replace it later with #synthesize field = field_; when I actually need the distinct ivar, say when it's custom-setter-writing time.)

Self-Learning XCode/Objective-C: 'static' doesn't seem to mean what I *think* it means

I'm working through examples in the book 'Visual Quick Start, Objective-C' by Holzner. I spend a lot of time with each example, getting the code debugged is the faster part, and then stepping through saying to myself why each line of code works, what each word in each line does and deciding why the author used one way of doing things versus another. Then I repeat the example with some story of my own. This seems to be a good way to move from being a structured programmer and to an oop-like one. It works with these examples because he just does one concept at a time. (I've worked part way through 2 other books and this idea did not work for me in those. Once I got confused by something, I just stayed confused. There were too many variables in the lengthier, more complex examples.)
In the current example (page 137), Holzner uses the word 'static'. I looked through examples in this book to decide what this word means. I also read the description in Bjarne Stroustrups' C++ Programming Language book (I understand that C++ and Objective-C are not exactly the same)
(Bjarne Stroustup p 145)
use a static variable as a memory,
instead of a global variable that 'might be accessed and corrupted by other functions'
Here is what I understand 'static' means as a result. I thought that meant that the value of a static variable would never change. I thought that meant it was like a constant value, that once you set it to 1 or 5 it couldn't be changed during that run.
But in this example piece of code, the value of the static variable does change. So I am really unclear on what 'static' means.
(Please ignore the 'followup question' I left commented in. I didn't want to change anything from my run, and risk creating a reading error
Thank you for any clues you can give me. I hope I didn't put too much detail into this question.
Laurel
.....
Program loaded.
run
[Switching to process 2769]
Running…
The class count is 1
The class count is 2
Debugger stopped.
Program exited with status value:0.
.....
//
// main.m
// Using Constructors with Inheritance
//Quick Start Objective C page 137
//
#include <stdio.h>
#include <Foundation/Foundation.h>
#interface TheClass : NSObject
// FOLLOWUP QUESTION - IN last version of contructors we did ivars like this
//{
// int number;
//}
// Here no curly braces. I THINK because here we are using 'static' and/or maybe cuz keyword?
// or because in original we had methods and here we are just using inheirted methods
// And static is more long-lasting retention 'wise than the other method
// * * *
// Reminder on use of 'static' (Bjarne Stroustup p 145)
// use a static variable as a memory,
// instead of a global variable that 'might be accessed and corrupted by other functions'
static int count;
// remember that the + is a 'class method' that I can execute
// using just the class name, no object required (p 84. Quick Start, Holzner)
// So defining a class method 'getCount'
+(int) getCount;
#end
#implementation TheClass
-(TheClass*) init
{
self = [super init];
count++;
return self;
}
+(int) getCount
{
return count;
}
#end
// but since 'count' is static, how can it change it's value? It doeeessss....
int main (void) {
TheClass *tc1 = [TheClass new] ;
printf("The class count is %i\n", [TheClass getCount]);
TheClass *tc2 = [TheClass new] ;
printf("The class count is %i\n", [TheClass getCount]);
return 0;
}
"static" is not the same thing as C++ "const". Rather it's a statement that a variable be declared only once and is to remain (hence static) in memory. Say you have a function:
int getIndex()
{
static int index = 0;
++index;
return index;
}
In this case the "static" tells the compiler to retain the index value in memory. Everytime its accessed it is changed: 1,2,3,... .
Compare this to:
int getIndex()
{
int index = 0;
++index;
return index;
}
This will return the same value each time as the index variable is being created each time: 1,1,1,1,1,... .
To clarify No one in particular's answer even further, a variable that is static will remain the same throughout all instances of objects, between method calls, etc.
For instance, declaring the following method:
- (int)getNumber {
static int number = 0;
return ++number;
}
will return 1, 2, 3, 4, etc., across all instances of the given class at any given time. Neat, eh?
static means many things in C / C++ / Objective-C.
Objective-C follows C closely. In C++, static means more things than in C / Objective-C. So, don't judge what static does in Obj-C by what Bjarne Stroustrup says (who is the inventor of C++).
In C and Objective-C, two main meanings of static are
For a variable / function in the file level, it makes a variable / function invisible from other translation units (i.e. other source files compiled into the same program.) It doesn't mean its constant.
For a variable declared inside a function, it makes a variable not to reside in a stack but in a more persistent location, as explained by no one in particular.
In C++, in addition to this meaning, a static member in a class means it belongs to the class, not to an instance. This meaning is completely unrelated to the other meaning; in the olden days, people didn't want to introduce more reserved words in the language, so they just abused the same reserved words in different contexts to mean completely unrelated things. Another notorious example is the usage of the word virtual.
In any case, static doesn't mean it's constant.
Anyway, in a programming language, a thing means whatever the implementers or the standard committee members decide it to mean. Therefore I find it always helpful to read the standard. Just look for the word static in that PDF. You'll learn everything about static keyword in the programming language C there.

Get the address of an Objective-c property (which is a C struct)

I have an Objective-C class which contains a C-style struct. I need to call a C function passing a pointer to this object member (a.k.a. property). For the life of me, I can't figure out how to get the address of this C struct. Using the traditional & operator to get the address, I'm getting an LValue compiler error.
typedef struct _myStruct
{
int aNumber;
}MyStruct, *pMyStruct;
#interface MyClass : NSObject {
MyStruct mystruct;
}
#property (readwrite) MyStruct myStruct;
#end
The following code results in a compiler error:
MyClass* myClass = [[MyClass alloc] init];
MyStruct* p = &(myClass.myStruct);
How do I get a pointer to the myStruct member of the myClass object?
There are often pretty good reasons to do what the original post is asking, given that Objective-C apps often have to work with C/C++ API's that take pointers to structs and similar types, but in a Cocoa app you'll often want to store such data in Objective-C classes for data management, collection in arrays and dictionaries, etc.
Though this question has been up for awhile I don't see the clear answer, which is: you can have a method that returns the address of the data that's backing your property, but in that method don't use "self" or it will go through the accessor and still not work.
- (const MyStruct*) getMyStructPtr
{
return &mystruct;
}
Note that I'm using the declared property from the OP, but not referencing it as self.mystruct, which would generate a compiler error (because that invokes the synthesized getter method).
MyStruct mystruct is private in MyClass, I assume when you do myClass.myStruct you are only refering to generated accessor method not the actual structure.
I don't think you can access the instance variable (structure in this case) from outside because it is private.
To get a pointer to the myStruct instance variable, you need to write a method that returns a pointer to that instance variable.
- (void)getMyStructPointer:(MyStruct **)outStruct {
*outstruct = &myStruct;
}
I don't really think this is a good idea, though. Other objects should not be mutating that object's ivar out from under it, and that's the only thing you can do with a pointer to the struct that you can't do with a copy of the struct returned by value.
The question itself demostrates a lack of understanding of at least the terminology.
A property is an interface consisting of two (or one for readonly) methods made public by the object, namely the getter and setter methods, in this case:
- (MyStruct) myStruct;
- (void) setMyStruct: (MyStruct) newMyStruct;
It makes no sense to talk about "taking the address of a property".
You can take the address of an instance variable (ivar). In this case you have an ivar named mystruct, and you can take the address of it with &mystruct in a method of MyClass. Since it is marked #protected (by default), you can take the address of it in a subclass using &self->mystruct. If you mark it #public, then you could take the address of it using &myobj->mystruct. This is a terrible idea, and you should really really rethink this, but you could do it.
If you just want the address of the ivar for some short lived purpose (for example, if MyStruct was large) you could do this, but it would be very unusual, and you'd be better off writing an explicitly named method like:
- (MyStruct*) getAddressForSettingMyStruct;
and if it is just read only, even better would be to use const MyStruct*.