What does the Asterisk * mean in Objective-C? - objective-c

Is it true, that the Asterisk always means "Hey, that is a pointer!"
And an Pointer always holds an memory adress?
(Yes I know for the exception that a * is used for math operation)
For Example:
NSString* myString;
or
SomeClass* thatClass;
or
(*somePointerToAStruct).myStructComponent = 5;
I feel that there is more I need to know about the Asterirsk (*) than that I use it when defining an Variable that is a pointer to a class.
Because sometimes I already say in the declaration of an parameter that the Parameter variable is a pointer, and still I have to use the Asterisk in front of the Variable in order to access the value. That recently happened after I wanted to pass a pointer of an struct to a method in a way like [myObj myMethod:&myStruct], I could not access a component value from that structure even though my method declaration already said that there is a parameter (DemoStruct*)myVar which indeed should be already known as a pointer to that demostruct, still I had always to say: "Man, compiler. Listen! It IIISSS a pointer:" and write: (*myVar).myStructComponentX = 5;
I really really really do not understand why I have to say that twice. And only in this case.
When I use the Asterisk in context of an NSString* myString then I can just access myString however I like, without telling the compiler each time that it's a pointer. i.e. like using *myString = #"yep".
It just makes no sense to me.

an * is actually an operator to de-reference a pointer. The only time it means "hey i'm a pointer" is during variable declaration.
Foo* foo // declare foo, a pointer to a Foo object
&foo // the memory address of foo
*foo // de-reference the pointer - gives the Foo object (value)

mmattax well covered the distinction between declaration (as a pointer) and dereferencing.
However, as to your point about:
(*myVar).myStructComponentX = 5;
to access a member of an instance of a C struct (as this is) you can do what you did , or more commonly you use the -> notation:
myVar->myStructComponentX = 5;
Objective-C is a little confusing here because it recently (in ObjC 2.0) introduced property syntax, which is a short cut for:
int val = [myObject someIntProperty];
and can now be written as:
int val = myObject.someIntProperty;
This is Objective C (2.0) syntax for accessing a property which you have declared (not an actual member variable), whereas your example was accessing a member of a C struct.
Make sure you are clear on the difference.

As I said in my answer of your previous question, #"yep" is already a pointer, so there is no need of * before myString which is also a pointer. In this case, you assign pointers not values.

Related

ObjC ternary operator and const strings

If you have a static const string, then its usage may cause inconsistent interpretation by the compiler. For example in this case:
const NSString* kUntitled = #"Untitled";
NSString* title = kUntitled;
the compiler will complain about assigning a const pointer to a non-const one ("discards qualifiers") and probably rightly so. This can be solved by either not using const at all, or by invoking kUntitled.copy (I somehow don't like the idea of typecasting (NSString*)kUntitled)
However, if you have instead:
NSString* title = aTitle ?: kUntitled;
then the compiler doesn't complain.
My first question is, can the warning be ignored in the first example? Are there any potential dangers in assigning a const NSString to a non-const one?
Second is, why does the compiler ignore the case with the ternary operator?
Welcome to the Weird and Wonderful World of C Declarations - the stuff of quiz questions ;-)
const NSString* kUntitled = #"Untitled";
You probably haven't written what you intended here. This defines kUntitled to be a mutable pointer to a "constant" string - usually referred to as a "pointer to a constant"... However it's "constant" for a reason as despite the common "pointer to a constant" it is actually a "read-only pointer" meaning you can read but not write via the pointer, what is pointed at might well be mutable but it is not mutable via this point if so...
Confused? What the above all means is that you can later write:
kUntitled = #"oops you probably thought you couldn't assign";
As the pointer itself is mutable, it can be changed to point at other things.
What you probably intended was:
NSString * const kUntitled = #"Untitled";
which declares a constant pointer to a string - it is the pointer itself which cannot be changed so:
kUntitled = #"this will produce a compile error, can't change a constant";
If you use this version of the declaration then you won't get an error on your assignments:
NSString* title = kUntitled;
NSString* title = aTitle ?: kUntitled;
However that still leaves the question of why you didn't get an error from the second with your original declaration...
The RHS of the assignment, aTitle ?: kUntitled is actually valid, the weird world of C again. This expression is just shorthand for aTitle ? aTitle : kUntitled and the rules for this operator in C state that the second and third arguments can be of the same base pointer type, NSString * in your case, but differ in qualifiers, const in your case, and the resultant type is the base pointer type with all the qualifiers of the two operands.
In other words the result of this expression is treated as const NSString *. Which means you should get the same warning as for the first assignment.
It appears that the compiler is treating the operator as though the resultant type is the base pointer type with none or only the common qualifiers of the two operands - i.e. the opposite of the definition.
So for the second problem you may have found a compiler bug, you should report it to Apple (bug reporter.apple.com) and see what they say.
HTH
The warning is a side effect of the fact that const NSString * kUntitled is incorrect. This is a declaration of a pointer-to-readonly-NSString. Note the placement of the "read only" there -- it's referring to the string, not the pointer. But ObjC objects are never read only, never const. You may say that literal NSStrings are, of course, but that's implementation dependent, and even modifiable in some runtime environments.
Thus you can never correctly assign this object anywhere else (unless that variable also was a pointer to a const object).
The declaration that you should be using is NSString * const kUntitled -- this is "readonly-pointer-to-NSString", i.e., the pointer cannot be changed to point at another object.

Objective-C Casting with Pointer [duplicate]

This question already has answers here:
Objective-C and Pointers
(3 answers)
why most of the objects we create in iphone are pointers
(1 answer)
Closed 9 years ago.
I am new to Objective-C and come from a Java background. I have just gone over casting in Objective-C but the book I am using failed to explain the use of the '*'/pointer when casting. Here is the example they gave me:
myFraction = (Fraction *) fraction;
Aren't pointers for specific objects so they have their own unique memory location? So then why must I use a pointer when simply referencing a class? In this case, Fraction.
Thanks I hope this makes sense and I know this is a simple question that I should know and understand but I could find nothing explaining this.
The * symbol has multiple meanings (beside multiplication :):
Dereference (follow) pointers. This code follows pointer stored in pointerToInt and then assigns a value to it.
(*pointerToInt) = 5;
Declares a pointer type. When you write int * it means “reference to an integer”.
int x = 5;
int * xPtr = &x
Now, objects are a kind of structures, but we only manipulate with them via pointers. Never directly. This basically means, that 99% of time when you see * (and it's not multiplication :) it is the second case: a part of type declaration:
NSString * = pointer to NSString structure (you can't use NSString alone)
Fraction * = pointer to Fraction structure and Fraction structure is described in Fraction class
So it's not “pointer to the Fraction class”, but rather “pointer to structure of Fraction class”.
I will go a little further and answer your future question about two **. You may see this usually with NSError arguments that are defined like methodWithError:(NSError **)errorPtr.
Short story: int is to int * as NSError * is to NSError **.
Long story: If we cannot manipulate with objects directly (without pointers to them), the single pointer becomes standard part of declaration. Now what if we want to make indirect access to the object? We use double pointer! First * is required for object, second is for indirection.
NSError *error = nil; // Empty.
NSError **errorPtr = &error; // Reference to our local `error` variable.
[data writeToURL:URL options:kNilOptions error:errorPtr];
// That method uses: (*errorPtr) = [NSError errorWith...];
NSLog(#"Error: %#", error); // Our local error is no longer empty.
I believe pointers are weird when you come from Java. They are a bit of legacy from C, but they are not used in any crazy way.
The * symbol is simply syntax that's used when referring to pointers.
Here, myFraction, and fraction are both variables that hold pointers (they aren't objects themselves – in fact you never have variables that hold Objective-C objects, objects must always be referred to with pointers).
The (Fraction*) syntax describes a cast to a pointer-to-a-Fraction of the expression on its right (in this case the fraction variable).
Remember that a pointer is just a variable that holds a memory location.
In Objective-C, when you have an object, what you really have is a pointer to an object, that is, a variable whose value is the memory address where the object really is.
Casting a pointer to a pointer of another type has no effect at runtime (at least for objects). In fact all your objects could be of type (void *). The casting helps the compiler to know what kind of object the pointer is pointing to, and generate errors or warnings.
If these two little paragraphs don't make much sense to you right now, consider reading some basic information or tutorials on pointers. Understanding pointers can be challenging for a beginner or from someone transitioning form the Java world.
...failed to explain the use of the '*'/pointer when casting...
Pointers have little to do with casting, other than being part of a type specifier. Consider:
Fraction is a type -- for the sake of argument, let's imagine that it's the name of a class, and that Fraction is a subclass of another class called Number.
Fraction * is a pointer to an instance of the Fraction class. In Objective-C, you always use pointers to refer to objects, so you'll see a lot of variables with types of the form ClassName *.
Casting is simply a matter of telling the compiler that it should treat a variable as a certain type. So, let's say you've got a variable number of type Number * and you know that the object it points to is actually a Fraction. However, you can't use any of the methods that are specific to Fraction because, as far as the compiler is concerned, number is just a Number *. You can use a type cast to tell the compiler: "I know what I'm doing, and number is definitely pointing to an instance of Fraction, so please treat number as a Fraction *." You do it like this:
Fraction *f = (Fraction *)number;
But again, the * doesn't have any special significance in the casting operation beyond the fact that Fraction * is the type to which you're casting number.

difference between self.myivar and self->myivar in objective-c

Hi I know that when accessing members in C using the arrow notation (->) makes elminates the need for using both star and dot (* .) every time an object needs to be accessed.
But in Objective-C is there any difference between self.myivar and self->myivar? I have noticed that both of them work in my case, where I have an myivar declared as a property.
But in Objective-C is there any difference between self.myivar and self->myivar?
Yes, there's a difference. Assuming that foo is a pointer to an object:
foo->bar is equivalent to (*foo).bar where the dot indicates the member access operator to get the instance variable bar.
foo.bar is equivalent to [foo bar]; that is, it sends the message -bar to the object pointed to by foo. That may just return whatever is in foo's bar instance variable, but it may do other things. There may not even be an instance variable named bar. As long as there's a method called -bar, however, foo.bar is valid. There should also be a -setBar: method if you're using foo.bar as the left hand side of an assignment, like: foo.bar = baz;.
Note that although self is a keyword in Objective-C, it always acts as a pointer to an object. There's nothing special about self with respect to accessing properties or instance variables. I've used foo as the name of the object pointer above to demonstrate that property/ivar access works the same way for any object pointer, but you could substitute self for foo above.

What does the Apple documentation mean when it refers to the correct place to include ARC attributes?

When casting around (no pun intended) to clarify when to use __strong in a variable declaration I came across these lines in the Transitioning to ARC Release Notes:
You should decorate variables correctly. When using qualifiers in an object variable declaration, the correct format is:
ClassName * qualifier variableName;
for example:
MyClass * __weak myWeakReference;
MyClass * __unsafe_unretained myUnsafeReference;
Other variants are technically incorrect but are “forgiven” by the compiler. To understand the issue, see http://cdecl.org/.
I suspect this is some sort of in-joke on Apple’s part, but I don’t suppose I get it. It clearly doesn’t matter but I would like to do it right. What is the importance of correctly “decorating” a variable declaration, and what point is cdecl.org trying to make?
Edit: to clarify, I want to understand precisely why writing
qualifier ClassName * variableName;
is "technically incorrect."
So I think I have an answer, but I can’t be sure if I’m correct. Feel free to provide a better one, or comment/upvote if you think I’ve nailed it.
CDecl is a C program which you can download from that same website. It exists to solve problems such as in this question.
Variable declarations in C can be pretty notorious, especially when typedefs are taken into account. There is a good introduction to this over at Unixwiz.net. You’ll find there a helpful introduction that will allow you to read even such monsters as char *(*(**foo [][8])())[]; (foo is array of array of 8 pointer to pointer to function returning pointer to array of pointer to char).
The rule with these is effectively proximity. Consider the simple example
const int * foo
This declares foo as a pointer to a constant int. However,
int * const foo
will declare foo as a constant pointer to an int. The subtle difference is discussed thoroughly in this question. (essentially, in the first example you can make foo point to another constant int, but cannot modify the constant int through foo; in the second, you can modify the int which foo points to, but you can’t make foo point to any other location in memory).
With these ARC attributes, the syntax of using
__strong NSString * myString
would declare myView as a pointer to a “strong” UIView. This is nonsensical. Only pointers to objects can have the attribute of being strong (or weak or whatever) under ARC. Therefore it is good practice to write
NSString * __strong myString
since this is in line with other C keywords.
I did ask myself: what happens under ARC if you declare a strong object pointer to a weak object pointer to, say, an NSString, like so
NSString * __weak * __strong myContrivedPointer;
but the same applies. Nothing but an object pointer can have these keywords. Consequently, it is nonsensical to declare a pointer to a pointer “strong”.

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.