the * in objective-C

Discussion in 'Mac Programming' started by ketels, Oct 16, 2010.

  1. macrumors newbie

    Joined:
    Oct 16, 2010
    #1
    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
     
  2. macrumors regular

    Joined:
    Jul 23, 2002
    #2
    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
     
  3. thread starter macrumors newbie

    Joined:
    Oct 16, 2010
    #3
    I think I almost get it...
    But I still don't understand why you don't write (UITableViewCell)*tableView since you write NSString *name;
     
  4. macrumors 6502a

    (marc)

    Joined:
    Sep 15, 2010
    Location:
    the woods
    #4
    The return type is always written inside of the parentheses. There's nothing to really "understand" here, it's syntax.
     
  5. macrumors 68000

    Sydde

    Joined:
    Aug 17, 2009
    #5
    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.
     
  6. macrumors 6502

    Joined:
    Jun 17, 2007
    #6
    It's the same thing to write

    Code:
    NSString *name
    as it is to write

    Code:
    NSString* name
     
  7. macrumors 603

    Joined:
    Aug 9, 2009
  8. macrumors member

    Joined:
    Jul 15, 2008
    #8
    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.
     
  9. macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
  10. macrumors 601

    HiRez

    Joined:
    Jan 6, 2004
    Location:
    Western US
    #10
    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.
     
  11. macrumors regular

    Joined:
    Mar 5, 2004
    #11
    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.

    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.
     
  12. macrumors 6502a

    GorillaPaws

    Joined:
    Oct 26, 2003
    Location:
    Richmond, VA
    #12
    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.
     
  13. macrumors 603

    Joined:
    Aug 9, 2009
    #13
    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.
     
  14. macrumors 601

    HiRez

    Joined:
    Jan 6, 2004
    Location:
    Western US
    #14
    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)
     
  15. macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #15
    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
     
  16. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #16
    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
     
  17. macrumors 68020

    Joined:
    Oct 12, 2006
    #17
    You can always do this too:
    NSString *thing1, *thing2;
     
  18. macrumors 601

    HiRez

    Joined:
    Jan 6, 2004
    Location:
    Western US
    #18
    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.
     
  19. macrumors 603

    Joined:
    Aug 9, 2009
    #19
    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.
     
  20. macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #20
    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.
     
  21. macrumors 68000

    Sydde

    Joined:
    Aug 17, 2009
    #21
    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.

    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.
     
  22. macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #22
    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;
    }
     
  23. macrumors 6502

    Joined:
    Mar 8, 2004
    #23
    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.
     
  24. macrumors 6502a

    GorillaPaws

    Joined:
    Oct 26, 2003
    Location:
    Richmond, VA
    #24
    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).
     

Share This Page