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

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”.

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.

Why does an object variable have to be a pointer?

If I declare an NSMutableString
NSMutableString *str_value;
Why do I have to declare this as a pointer (using *)? If I don't, I get a compilation error.
Could someone explain this clearly?
Recall that Objective C is a superset of C. When you declare a variable without * in C, it is an indication that the memory for that variable is allocated either in the automatic storage if it is a local variable, as part of its outer structure if it is a member of a structure, or in the static memory if it is a static or a global. Using the typename or a structure tag without * in a parameter list of a function indicates passing by value.
The designers of the Objective C language could have taken the Java-like route, making every class instance is a pointer without the pointer syntax, but then the readers of programs in Objective C would need to know if a name represents a typedef based on a struct or an id type to answer even the most basic questions about objects of that type, such as if it is implicitly passed by pointer or by value, if it is allocated as part of the owning structure or as a heap object pointed to by a pointer inside the structure, and so on.
To avoid this kind of confusion, designers of Objective C decided to preserve the explicit pointer syntax for id objects.
A pointer means you are pointing / referencing to that class. Yes it will cause a compilation error, the reason for a pointer is mainly for memory. One data type (int or BOOL or float etc...) is only a few bytes, therefore it is not necessary to have a pointer. But NSMutableString and other Objective-C classes have a lot of properties and methods, with a lot of code. Therefore, since in your apps will have a lot of objects, which will use a lot of memory and thus slow down your app/decrease performance. Of course you should release the object once you make a pointer.

Why is it a pointer? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
objective c difference between id and void *
why most of the objects we create in iphone are pointers
According to Stanford university course, 2010/2011
Lecture 3
The guy made something strange there (at least for me), which is that
NSString *digit = sender.titlelabel.text;
Why is digit a pointer?
The type of your digit is id, which is just basically just a C pointer to a certain struct. All references to objects in Objective-C have this primitive type, regardless of the Class of the object. So the answer to your question is, unfortunately, because that's the way Objective-C works.
So whether you're declaring an NSString*, or an UITableViewController*, or MyClass*, your variable has type id. This is the primary means by which the language implements polymorphism. So, for example, the following declarations are equivalent:
NSString *digit;
id digit;
And it's true of method prototypes as well. These are equivalent:
-(UITableViewCell *)tableView:(UITableView)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
-(id)tableView:(id)tableView cellForRowAtIndexPath:(id)indexPath;
A variable of type id is not an object itself, it is a pointer to an object. It is the handle with which you manipulate an object. Objective-C does all of the class compatibility work at runtime.
Hope this helps. Any questions?
Updates
That's right: int, float, double, char, void, and the pointer combinations, are all C primitive types. You can and will still use these quite a bit, and they are just what they are in a C program. But Objective-C adds the id type as a way to bridge the gap between the primitive typing of C and the very high-level typing of objects by the Objective-C system. id itself is typedef'd as a pointer to a simple struct in objc.h. At the level of the compiler and the language itself, there really isn't too much meaning to the type. For example, you'll almost never declare an array of ids, certainly never perform any arithmetic with them.
In fact, it's not too far a stretch to say that Objective-C is just plain vanilla C with some added syntax (particularly, the square-bracket notation for method invocation), a few extra primitive types (id, IMP, SEL), and a big runtime library. It's this runtime library that handles all things Object-Oriented.
Anyway, to answer your question, when you're actually programming, you will most often (99% of the time) just use class names to declare your variables - NSString *, NSData *, UITableViewController *, and so on. And the compiler will know what you're talking about, and issue a warning if you write code that clearly tries to put an NSString* where an NSData* is expected. But the actual meaning of those types really exists only at runtime.
I've digressed a little, but I'm not sure where your understanding is failing you, so I thought I'd just explain things a bit. You might want to read Apple's The Objective-C Programming Language to get a feel for the language.
NSString is an Objective-C class and all object references in Objective-C are pointers. I would suggest reading through some of the documentation such as Learning Objective-C A Primer:
Notice the * in the first declaration. In Objective-C, object
references are pointers. If this doesn’t make complete sense to you,
don’t worry—you don’t have to be an expert with pointers to be able to
start programming with Objective-C. You just have to remember to put
the * in front of the variable names for strongly-typed object
declarations. The id type implies a pointer.
It's not a digit, it's the "text" from the label, which is (I'm guessing) a string of integers and such to express the time.
So, all NSString types are declared as pointers in Obj-c.
sender.titlelabel.text;
Returns a NSString *
Remember, it's the same as:
NSString *str = [sender.titlelabel getText];
Because text is too. Or more preceisly, because the getText message returns a pointer.
You can find an intersting about why it has to be a pointer:
NSString and Pointers
I Hope it will help you to understand it in a Objective-C way.

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.

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.