The asterisk in Objective-C object instance declarations: by the Object or by the instance? [duplicate] - objective-c

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What's your preferred pointer declaration style, and why?
In C, why is the asterisk before the variable name, rather than after the type?
What makes more sense - char* string or char *string?
When declaring a new instance of an object in Objective-C, does it make any difference where you put the asterisk?
Is this just a matter of personal preference?
NSString* string = #"";
vs.
NSString *string = #"";

It doesn't make a difference, but there are good reasons to put it in each place:
It makes sense to put it near the class, because that makes it feel like a type: NSString*, a pointer to a string. Sensible.
It makes sense to put it near the variable, because that's what's actually happening: * is dereference. When you dereference your pointer string, you get an NSString. *string is an NSString. Sensible.
You may want to go with the latter because that's the way the compiler is thinking, so: NSString* oneString, anotherString will not work, whereas NSString *oneString, *anotherString is correct.

It's simply a matter of preference. Putting the * next to the type emphasizes that it's part of the type, i.e. "pointer to an NSString". However, this is usually frowned upon, because it ignores the fact that the * associates with the nearest variable name, not the type name. For instance, the following doesn't work:
NSString* a = #"string1", b = #"string2
This is because a is a pointer, but b is not.
Putting the * next to the variable name is, in my opinion, more of a C/C++ convention, because it emphasizes that the * and the variable name together act kind of like a variable.
Personally, I put a space on both sides of the *.
Another question that asked the same thing is here:
Declaring pointers; asterisk on the left or right of the space between the type and name?

It doesnt make the difference wher you put that pointer symbol. If you declare multiple objects in single line, you do it like NSString *str1, *str2. So its more appropriate to put that asterisk close to object. I prefer it close to object instance.

Related

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.

To pointer or not to pointer? Or is this a pointer at all?

Alright, it's been a long time since I've worked with pointers. And now I've been writing .NET code for more than a decade so I haven't had to deal with them. In fact, in .NET it's really nice because if it's not a value type then it's clearly a reference type, or by definition a pointer.
So, in .NET when I declare a string it's most certainly a pointer underlying because it's a reference type:
string s = "Hello Mike!";
However, it appears that in Objective-C I can declare a string two different ways:
NSString* s = "Hello Mike!";
NSString s = "Hello Mike!";
Now, if I'm understanding this correctly the first declaration is very similar to the underlying declaration of a string in .NET, a pointer. But what exactly is the second?
Now bear in mind I may be way off base here because I'm just starting to dig into Objective-C, so please excuse my ignorance!
Neither of your NSString declarations should actually compile. The first should tell you that it's an incompatible assignment because your assigning a C string pointer as if it were an object address. The second should tell you that you can't actually declare an object, only a pointer to an object. The correct syntax is:
NSString* s = #"Hello Mike!";
In this case, s is a pointer variable which contains the address of a string object, having the "Hello Mike!" value.
Coming from REALbasic to Objective-C was similar for me: they both use pointers as references to object instances, but in REALbasic that fact is implicit, whereas Objective-C is C and therefore must make it explicit. That fact, however, is really just an accident of notation. The implications, for things like assignment and comparison, are similar.
You might be helped by reading the relevant entry from my book on this topic:
http://www.apeth.com/iOSBook/ch03.html#_an_instance_reference_is_a_pointer
(The fact that you don't seem to understand yet how to form an NSString literal (it starts with an at-sign, e.g. #"hello", is secondary.)

What does assigning a literal string to an NSString with "=" actually do?

What does the following line actually do?
string = #"Some text";
Assuming that "string" is declared thusly in the header:
NSString *string;
What does the "=" actually do here? What does it do to "string"'s reference count? In particular, assuming that for some reason "string" is not otherwise assigned to, does it need to be released?
Thanks!
The assignment is just that. The string pointer is basically a label that points to specific address in memory. Reassignment statement would point that label to another address in memory!
It doesn't change reference counting or do anything beyond that in Objective-C. You need to maintain the reference count yourself, if you are running in a non-garbage-collection environment:
[string release];
string = [#"Some text" retain];
However, string literals don't need to be managed, as they get allocated statically and never get deallocated! So the release and retain methods are just NOOPs (i.e. no operations). You can safely omit them.
What does the following line actually do?
string = #"Some text";
Assuming that "string" is declared thusly in the header:
NSString *string;
What does the "=" actually do here? What does it do to "string"'s reference count?
string is not a string.
string is, in fact, not any other kind of Cocoa object, either.
string is a variable, which you've created to hold an instance of NSString. The assignment operator puts something into a variable*. In your example above, you create a literal string, and put that into the variable.
Since string is a variable, not a Cocoa object, it has no reference count.
Assigning an object somewhere can extend the object's lifetime in garbage-collected code (only on the Mac). See the Memory Management Programming Guide for Cocoa for more details.
*Or a C array. Don't confuse these with Cocoa arrays; they're not interchangeable, and you can't use the assignment operator to put things into a Cocoa collection (not in Objective-C, anyway).
When you use a literal like in this case, it is just syntactic sugar to quickly create an NSString object. Once created, the object behaves just like another other. The difference here is that your string is compiled into the program instead of created dynamically.

What's the difference?

I'll preface my question by saying that I'm a beginner objective-c developer. What is the difference between:
NSString * foo;
NSString* foo;
NSString *foo;
Is there a difference?
All three simply declare a variable named foo of type NSString *. It is really just a matter of style preference.
Some people prefer to put the asterisk next to the type to emphasize that this is a pointer type.
Some people prefer to put the asterisk next to the variable to emphasize the requirements of the language. Every pointer variable in a multiple declaration needs to have the asterisk, as in:
NSString *foo, *bar;
My personal preference is actually the first of your examples with a space before and after the asterisk, reserving the use of an asterisk directly before the variable for use in dereferencing the pointer. I also avoid declaring more than one variable in a single declaration.
There is no difference, they mean all three the same thing. Only it is considered to be better to declare it like:
NSString *foo;
Because when you add a second variable your intention is more clear:
NSString *foo,*bar;
No difference. The three work the same.
The difference is that you have the space in a different location in each example :-)
Semantically, there is no difference whatsoever. Stylistically, the last form is preferred.

What does the Asterisk * mean in 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.