Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

ketels

macrumors newbie
Original poster
Oct 16, 2010
2
0
I'm trying to learn Objective-C, but there is one thing I do not really get a grip on.
I understand that if one writes:
Code:
NSString *name;
it is a pointer to NSString object.

But why do you write the star inside the brackets when you write:
Code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

Why not write:
Code:
- (UITableViewCell)*tableView
 

crackpip

macrumors regular
Jul 23, 2002
210
0
I'm trying to learn Objective-C, but there is one thing I do not really get a grip on.
I understand that if one writes:
Code:
NSString *name;
it is a pointer to NSString object.

But why do you write the star inside the brackets when you write:
Code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

Why not write:
Code:
- (UITableViewCell)*tableView

The bit inside the parentheses indicates the datatype of the arguments or the function result. In Obj-C you don't pass/return objects directly, you pass/return pointers to objects. So (UITableViewCell *) means the function will return a pointer to a UITableViewCell object.

crackpip
 

ketels

macrumors newbie
Original poster
Oct 16, 2010
2
0
The bit inside the parentheses indicates the datatype of the arguments or the function result. In Obj-C you don't pass/return objects directly, you pass/return pointers to objects. So (UITableViewCell *) means the function will return a pointer to a UITableViewCell object.

crackpip

I think I almost get it...
But I still don't understand why you don't write (UITableViewCell)*tableView since you write NSString *name;
 

(marc)

macrumors 6502a
Sep 15, 2010
724
2
the woods
I think I almost get it...
But I still don't understand why you don't write (UITableViewCell)*tableView since you write NSString *name;

The return type is always written inside of the parentheses. There's nothing to really "understand" here, it's syntax.
 

Sydde

macrumors 68030
Aug 17, 2009
2,552
7,050
IOKWARDI
The syntax is basically a typecast. For example, if you were to declare
Code:
int *someInt;
float *someNum;
and for some reason needed to assign one pointer to the other, you would use similar syntax
Code:
someInt = (int *)someNum;
to cast the type. This is for tranferring a pointer. If you wanted the referenced value, "aFloatingPointNum = (float)*someInt;" is the syntax you would use.
 

amorya

macrumors 6502
Jun 17, 2007
252
7
I think I almost get it...
But I still don't understand why you don't write (UITableViewCell)*tableView since you write NSString *name;

It's the same thing to write

Code:
NSString *name

as it is to write

Code:
NSString* name
 

Stratoukos

macrumors member
Jul 15, 2008
51
0
As amorya said, I think you are confused by the syntax.

In Objective-C, as in most languages that have pointers, a pointer to something is a distinct type from a pointer to something else. So a pointer to int is neither a pointer to something that happens to be an int nor an int that happens to be pointed at. It's a type of its own.

When declaring a variable, the syntax is:
Code:
[b]type[/b] name
So, when the variable is a pointer to NSString, the syntax is:
Code:
[b]NSString *[/b]name
The fact that there isn't any space between * and the name is confusing. The * logically belongs to the type.

When declaring a method, the syntax is:
Code:
-([b]returnType[/b])methodName:([b]parameterType[/b])variableName;
So, when, for example, the method takes a pointer to NSString and returns a pointer to UITableViewCell, the syntax is:
Code:
-([b]UITableViewCell *[/b])methodName:([b]NSString *[/b])variableName;

Just remember that the fact that a variable is a pointer is about its type, not its name.
 

HiRez

macrumors 603
Jan 6, 2004
6,250
2,576
Western US
You're right to be confused, because it is confusing. The * symbol probably causes more confusion in C than anything else, and it's one of the reasons that other derived languages such as Java have tried to eliminate it. Inconsistencies like Apple's "id" addition don't help.
 

vocaro

macrumors regular
Mar 5, 2004
120
0
The syntax is basically a typecast.

No! The "(UITableViewCell *)" in ketels's snippet is simply a declaration of the method's return type. This is definitely not an example of typecasting.

The * logically belongs to the type.

Yes, precisely. This is not so much a syntax issue as a whitespace issue. Instead of:

Code:
NSString *name;

it would actually be more correct to write:

Code:
NSString* name;

to more clearly indicate that the asterisk is part of the variable's type, not its name. Some programmers do use the latter convention for this very reason, but somehow the former has taken hold, illogical as it is.
 

GorillaPaws

macrumors 6502a
Oct 26, 2003
932
8
Richmond, VA
Some programmers do use the latter convention for this very reason, but somehow the former has taken hold, illogical as it is.

I can remember being very confused by this when I was first learning (especially because it was inconsistent from programmer to programmer). I think this is one of those issues where freedom of whitespace makes things less clear.
 

chown33

Moderator
Staff member
Aug 9, 2009
10,740
8,416
A sea of green
Some programmers do use the latter convention for this very reason, but somehow the former has taken hold, illogical as it is.

It's logical when you consider this won't work:
Code:
NSString* name, city;
Then it becomes clear that * is a modifier that must appear for every declared pointer variable.
 

HiRez

macrumors 603
Jan 6, 2004
6,250
2,576
Western US
It's logical when you consider this won't work:
Code:
NSString* name, city;
Then it becomes clear that * is a modifier that must appear for every declared pointer variable.

Yep, that's the problem. However, I always declare only one variable per line no matter what. Then, not a problem.

Code:
NSString* name;
NSString* city;

I find the one declaration per line rule also helps when adding or deleting variables, and adding comments (you can easily add // after the variable without having to break it out into its own line)
 

jared_kipe

macrumors 68030
Dec 8, 2003
2,967
1
Seattle
I agree with both of you. I personally prefer to write NSObject *object; as its what you see in the documentation and sample code.

However I almost ALWAYS will declare objects one per line. And usually primatives all at once. As long as they are somewhat related.
E.G.

int counter, errorCount;
double stdDev, mean, range;

NSArray *inputArray;
NSArray *outputArray;

// actual code for method blah blah
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
However I almost ALWAYS will declare objects one per line. And usually primatives all at once.

What about pointers to primitives or structs? That seems like the more ambiguous case, since missing a * on an Object will be a compile-time error for sure, while missing one on a primitive pointer might just lead to warnings and erroneous run-time behavior.

-Lee
 

Matthew Yohe

macrumors 68020
Oct 12, 2006
2,200
142
I find the one declaration per line rule also helps when adding or deleting variables, and adding comments (you can easily add // after the variable without having to break it out into its own line)

You can always do this too:
NSString *thing1, *thing2;
 

HiRez

macrumors 603
Jan 6, 2004
6,250
2,576
Western US
You can always do this too:
NSString *thing1, *thing2;

For sure, but the point was to keep the * next to the type so it reads more obviously as "string pointer" (or whatever). I think logically that makes more sense, but it's become somewhat standard to do it the "less logical" way. People like to save lines, but Objective-C is such a verbose language anyway, I think it makes sense to strive for more clarity and less compactness where possible. Just my opinion, I know a lot of old school C coders still see the beauty in a bit of code that's as terse and compact as possible.
 

chown33

Moderator
Staff member
Aug 9, 2009
10,740
8,416
A sea of green
... I know a lot of old school C coders still see the beauty in a bit of code that's as terse and compact as possible.

Until they have to perform maintenance on that code. Then they curse the idiot who made it that way. Even when (or especially when) that idiot is the younger version of themselves.

You laugh and shake your head, but you know it's true, because you've seen someone else do it, or done it yourself.
 

jared_kipe

macrumors 68030
Dec 8, 2003
2,967
1
Seattle
What about pointers to primitives or structs? That seems like the more ambiguous case, since missing a * on an Object will be a compile-time error for sure, while missing one on a primitive pointer might just lead to warnings and erroneous run-time behavior.

-Lee

Can't remember the last time I needed to declare more than one pointer to a struct or primitive. So it would probably depend on my mood if the time arose.
 

Sydde

macrumors 68030
Aug 17, 2009
2,552
7,050
IOKWARDI
As I recall, I have seen compiler error messages that refer to the indirection symbols "*" and "&" as unaries. Like "+" or "-" before a numeric value, the pointer unaries are modifiers applied to the variable that follows.

For example, you could declare a pointer variable with no whitespace at all
Code:
NSString*aString;
or with whitespace on both sides of the "*". I think the proper description of declaration syntax is
Code:
type location name;
where location is zero or more "*" indirection unaries. If you tie the unary to the type, you might end up with confusion or mental discomfort when you have to deal with double indirection.

No! The "(UITableViewCell *)" in ketels's snippet is simply a declaration of the method's return type. This is definitely not an example of typecasting.
Sorry, I did not mean to say that it was a typecast, just that that is how the syntax makes sense as an extension C grammar.
 

jared_kipe

macrumors 68030
Dec 8, 2003
2,967
1
Seattle
Sorry, I did not mean to say that it was a typecast, just that that is how the syntax makes sense as an extension C grammar.

Not really, that part of C grammar is for return type. In objective-C the return type is in () but in C it is not.

int add( int a, int b) {
return a+b;
}
vs
+ (int)addInt: (int) a toInt: (int) b {
return a+b;
}
 

Mac_Max

macrumors 6502
Mar 8, 2004
404
1
Until they have to perform maintenance on that code. Then they curse the idiot who made it that way. Even when (or especially when) that idiot is the younger version of themselves.

You laugh and shake your head, but you know it's true, because you've seen someone else do it, or done it yourself.

Good code comments and documentation goes a long way. I tend to over comment/over document since the penalty for that is a lot less than not knowing what you're looking at.
 

GorillaPaws

macrumors 6502a
Oct 26, 2003
932
8
Richmond, VA
Good code comments and documentation goes a long way. I tend to over comment/over document since the penalty for that is a lot less than not knowing what you're looking at.

That was the approach I started out with. I recently read Clean Code and my views on comments have shifted since then. Basically, the authors recommend breaking out chunks of code that you would typically explain with comments, and creating a well-named private methods as a more elegant replacement.

I've also heard that comments should focus on WHY you are doing something, and not a description of WHAT the code is doing. If you have to explain what your code is doing with comments then your code isn't very clearly written. It's my new coding philosophy for now, and I don't pretend to have nearly the knowledge and experience as many of you guys, but I really like the approach they take in "Clean Code" (except for the test driven development stuff--I'm not ready for that just yet).
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.