Trying to understanding "self"

Discussion in 'iOS Programming' started by animefx, Jul 27, 2012.

  1. animefx macrumors regular

    Joined:
    May 10, 2005
    Location:
    Illinois
    #1
    I've been making my way through Steve Kochan and the Nerd Ranch books on Objective-C and I'm having some issues with their explanations for when to use "self" and I've looked online a little bit and haven't found that good of an explanation for it.

    How does the program know what "self" is when it is part of your syntax? Why wouldn't someone just use what self is actually called wheather it be a UITextView, UIViewController, a table, etc?
     
  2. Reason077 macrumors 68000

    Reason077

    Joined:
    Aug 14, 2007
    #2
    "self" refers to the current instance of the class you are writing.

    It can only be used within instance methods (sometimes known as member functions) of a class. In ObjC, that means methods that are declared with "-".

    If you're alloc'ing and using a UITextView, then you refer to it with a variable name like "textView" or whatever.

    But when you're writing your own class, such as MyViewController, then you refer to the current instance of the class you're writing as "self".
     
  3. PhoneyDeveloper macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #3
    Do you know the difference between a class and an object?

    self is THIS object.

    THIS class is UITextView (or some other class name).
     
  4. ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #4
    Think about it this way.

    You yourself are an instance of the class Person. When you think your thoughts in your head, you keep them to yourself. You don't (or shouldn't) be sharing your personal thoughts with other Persons.

    Similarly, for instance (internal) methods, your instances should refer to self, themselves, rather than to their class.
     
  5. animefx thread starter macrumors regular

    Joined:
    May 10, 2005
    Location:
    Illinois
    #5
    Ok thanks for the replies everyone, but I want to be clear I'm understanding this.

    If I have an an instance of the class Person called "Bryan" and I'm calling methods on this instance why would I need to every specify "self"? [Bryan setAge:33]; wouldn't confuse anything with say another instance of Person called "Charlie".

    Are you guys saying if I have to use a Person class *within* the implementation of Person instead of saying [Bryan setAge:33]; I wouldn't need to create an object, and I wouldn't want to change the values of instance variables in Person permanantley so I would instead do [self setAge:33]; ? Or am I still not grasping the concept?

     
  6. samdev, Jul 27, 2012
    Last edited: Jul 27, 2012

    samdev macrumors regular

    Joined:
    Sep 16, 2011
    #6
    To me, "self" is the same thing as the this pointer in C++.
     
  7. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #7
    What about [self foo] then? ;)

    You can have no properties but find the need to use self.
     
  8. animefx thread starter macrumors regular

    Joined:
    May 10, 2005
    Location:
    Illinois
    #8
    I'm still not understanding what is actually happening and when to use self. If Person is my class I'll make plenty of instances of that class but I will always know the name of that instance I'm using methods on.

    Is self referring to Person or to an instance of person? Or is self an instance of Person?
     
  9. 1458279 Suspended

    1458279

    Joined:
    May 1, 2010
    Location:
    California
    #9
    I don't think you will ALWAYS know what instance you are dealing with...

    Someone correct me if I'm wrong:

    Self refers to an instance of a class, never a class.
    I don't think you must use self, I think you could write the whole program without using self and only refer to the instance by direct name IE: [Bryan setAge:33]

    [Bryan setAge:33] and [self setAge:33] are only the same _IF_ Bryan is the current instance.


    Instance of person

    You might want to think of it like this:
    'this' helps the compiler know what you are referring to. If you don't use 'this' the compiler might not know which instance you are referring to.

    This is helpful if you are inside of one method and want to perform an action on another instance or several different instances.

    Just think of it as adding clarity, so the compiler knows what you mean.
     
  10. animefx thread starter macrumors regular

    Joined:
    May 10, 2005
    Location:
    Illinois
    #10
    I was definitely over thinking this. It makes complete sense to me now! I might have a thousand instances of the Person class. In the implementation of one of it's methods I might want to refer to, or do something with whatever instance had called it, and it that case I would use "self"

    Thanks for the help on this everyone!

     
  11. firewood macrumors 604

    Joined:
    Jul 29, 2003
    Location:
    Silicon Valley
    #11
    A method operates on data, and can be passed parameters, just like a subroutine. "self" is the name of an invisible parameter passed to a method, just like the visible parameters to a C subroutine.

    "self" a special type of subroutine parameter, as it is a pointer to an object instance of the same class as that of the method, which helps pick which subroutine to call, if there are many of the same name, and how the subroutine knows what type of data on which it is operating.
     
  12. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #12
    Not the instance that called it. That's backwards.

    In object-oriented programming, you send messages to objects. (to instances of an object.)

    The messages invoke instance methods.

    An instance method is a method that's run by an instance of an object.

    If you have a car class, there might be multiple models of car. Each car has a unique VIN (a serial number) it has a unique maintenance history; it has unique stations stored on it's radio; it has a gas level that's different from every other car, it has wear levels for all it's parts, and it likely has a unique set of scratches and dents.

    If you send a car a turnOnRadio message, it will turn the radio on THAT car, to the last radio station that was played. The code might look like this:

    Code:
    -(void) turnOnRadio;
    {
      self.radio sateStationTo: self.lastStationPlayed
      [self.radio setToOn: TRUE];
    }
    
     
  13. ArtOfWarfare macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #13
    Another example is delegation... in a project I'm working on now, I have a several objects that load information about themselves from XML files. To do that, they have to create NSXMLParsers. These parse XML files and return info about the files to their delegates. So I have code that looks like this:

    Code:
    NSXMLParser* parser = [[NSXMLParser alloc] initWithContentsOfURL:URL];
    parser.delegate = self;
    [parser parse];
    The info the parser finds needs to be returned to this specific instance of my class, not just any instance.
     
  14. xStep macrumors 68000

    Joined:
    Jan 28, 2003
    Location:
    Less lost in L.A.
    #14
    Maybe the following will help the discussion.

    Self refers to the object or class you are currently executing within. In the case of class methods, the ones with a plus sign, referring to the class name or self is the same thing as they are both pointers pointing to the same object. Yes, a class is also an object. Referring to a class method from an instantiated object of a class using self will not work because self is pointing to an object instance. Check out the sample...

    The foo class method can use either its class name or self to access another one of its class methods because they are pointing to the same object. When executing within foo, you are also executing within the class object.

    The bar instance method can only use the class name to access the fourtyTwo method because self points to an instantiated object of the class which is therefor a different independent object.

    Code:
    + (NSUInteger) fourtyTwo
    {
        return 42;
    }
    
    + (void) foo
    {
        NSLog(@"Class call: %d  Self call: %d", [MyClass fourtyTwo], [self fourtyTwo]);
        NSLog(@"Class pointer: %@  self pointer: %@", [MyClass self], self); // Both print MyClass text.
    }
    
    - (void) bar;
    {
        NSLog(@"\n");
        NSLog(@"Class call: %d", [MyClass fourtyTwo]);
        NSLog(@"A [self fourtyTwo] call causes error:  No visible @interface for 'MyClass' declares the selector 'fourtyTwo'");
        NSLog(@"Instance self pointer: %@", self); // Prints expected value format indicating class and an instance id: <MyClass: 0x713cbb0>
    }
    
    From another object I do the following to see the result.
    Code:
        [MySelf foo];
    
        MySelf * mySelf1 = [MySelf new];
        [mySelf1 bar];
    
        MySelf * mySelf2 = [MySelf new];
        [mySelf2 bar];
    

    A side note: The class methods 'stick' to the class object. The short answer for instance variables and instance methods is that they get assigned an independent block of memory for each instance created.
     
  15. NickFalk macrumors 6502

    NickFalk

    Joined:
    Jun 9, 2004
    #15
    It might make more sense to you if you consider the fact that you are generally not calling methods inside your code, but sending messages to Objects.

    So if you have a few code of lines like this:
    Code:
    NSMutableArray *sillyNamedMutableArray = [[NSMutableArray alloc] init];
    NSString *aName = [[NSString alloc] initWithString:@"Nick"];
    [sillyNamedMutableArray addObject: aName];
    
    In that last line it shouldn't be hard to wrap your head around the idea that you are sending the sillyNamedMutableArray the message to add the object aName.

    Now, when you need to send a message to an instance of the object you're working on you won't have the instance name, so you'll send the message to self instead.

    For instance if you have a class called person you might have a method called -(void) increaseAge;

    This might not be a public method and is only used internally. Let's say some other class feeds the class a date:
    Code:
    PersonClass *somebodyThatIUsedToKnow = [[PersonClass alloc] initWithAge:39];
    PersonClass *someoneElse = [[PersonClass alloc] initWithAge:27];
    .
    .
    .
    // much later...
    [somebodyThatIUsedToKnow checkForBirthdayWithDate: todaysDate];
    [someoneElse checkForBirthdayWithDate: yesterdaysDate];
    
    (Yest this in convoluted), anyway your Person class might handle this something like this...
    Code:
    -(void)checkForBirthdayWithDate: (NSDate *) receivedDate{
       BOOL birthdayNow = [self isBirthdayEqualToDate:receivedDate]; // not writing this method
       if (birhdayNow){
          [self increaseAge];
       }
    }
    
    -(void) increaseAge{
       age++;
    }
    
    Now if you look at the method names the self thing might make more sense (or not). "self" will send the message to whatever instance of the current object it is asked to.
     
  16. firewood macrumors 604

    Joined:
    Jul 29, 2003
    Location:
    Silicon Valley
    #16
    Which ordinary CPUs do by calling subroutines (within the namespace of some given class, and containing a hidden address pointer to a data blob representing the stuff inside an object). "self" is just another name for this particular data blob.

    The whole "message" thing is merely a fictional abstraction. If this helps, great. If not, ignore the fiction.
     
  17. NickFalk macrumors 6502

    NickFalk

    Joined:
    Jun 9, 2004
    #17
    The main point of any high-level language is in a sense abstraction. Otherwise we'd all be writing assembler. Ignoring conventions of any given language is only asking for trouble, particularly when trying to learn a language.

    Naming conventions in existing frameworks takes this into consideration when naming methods and ignoring these "rules" only results in making code harder to read/debug down the line. I'm hard pressed to see any goods reason why anyone should ignore this...
     
  18. firewood macrumors 604

    Joined:
    Jul 29, 2003
    Location:
    Silicon Valley
    #18
    You are assuming that all language conventions are helpful in all situations. That is an interesting but unproven hypothesis.

    BTW. Some portions of high performance iOS apps are often written in assembler (higher level ARM NEON intrinsics were only a recent addition to the SDK).

    When debugging a crash, sometimes all one has are the bits and bytes in memory and a program counter. Best to know how they got there and what they should be.
     
  19. NickFalk macrumors 6502

    NickFalk

    Joined:
    Jun 9, 2004
    #19
    No I'm not. However: When you follow conventions it will make it easier for others to understand your code making it closer to being self-documenting. If everyone follows conventions everyone are at the same page and you avoid disambiguity.
    By all means, assembler has its place and this will always be the case. Not quite sure what this has to do with anything in this thread though. :confused:
    Yes I agree that understanding the underlying technology is good thing. The point of following conventions is to make it easier to avoid creating bugs in the first place.

    As for "calling methods" vs. "sending messages" there are some reasons why the second makes more sense technologically as well as linguistic. As Objective-C allows you to send messages to nil without crashing for instance. You obviously would call the method of nil, would you?

    It seems our main disagreement is that you believe ignoring conventions is a good thing. :confused: While I am a sound believer that conventions should always be followed unless you have a really clear idea why not too.
     
  20. firewood macrumors 604

    Joined:
    Jul 29, 2003
    Location:
    Silicon Valley
    #20
    I do not propose that ignoring conventions is a good thing. Conventions should be used when useful, and not when not. One should have a clear idea both ways.

    If one has to beat someone over the head to get them to use some precision machinery, perhaps one should try letting them use a simple screwdriver instead and see if they do better, and without the head injury. The OP wasn't grokking the precision machinery, so I tried to hand him a screwdriver... the simple type successfully used for decades.
     
  21. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #21

    It's like arguing on the internet...
     
  22. admanimal macrumors 68040

    Joined:
    Apr 22, 2005
    #22
    Not to confuse things further, but you can use self in class methods. It will refer to the current Class. Using self in class methods is often essential for subclassing to work correctly.

    See here for more info: http://stackoverflow.com/questions/5987969/class-methods-which-create-new-instances/5988016#5988016
     
  23. solderguy1, Aug 1, 2012
    Last edited: Aug 1, 2012

    solderguy1 macrumors member

    Joined:
    Apr 20, 2012
    #23
    For any newbies, make sure you don't miss the forest for the trees.

    Object oriented languages are basically just a bunch of objects calling each other's methods. To do this, you need the reference name (or pointer if you will) that the other object was instantiated under.

    For simple programs with one object instantiated per class, the programmer can use the classname with a lowercase first letter or my{classname}. For example: myCat for a instance of the Cat class.

    Self is just a reference or pointer to call methods and ivars in the object that's currently running code. You are calling your object's own methods, not those of another object.

    Way oversimplified example follows. Make sure this is clear before moving onto class methods, objects stored in collections, and all that.


    Code:
    @interface PetOwner
      bool tummyFull;
    @end
    
    @implementation PetOwner
    - (void) init
    {
      myDog = [[Dog alloc]init];
      myCat = [[Cat alloc]init];
    }
    - (void)consumeEveningMeals;
    {
    	[myDog eatFood];  //another object's method
    	[myCat eatFood];  //another object's method
    	[self eatDinner];   // homegrown method
    }
    
    -(void)eatDinner
    {
      NSLog(@"Yes the pet owner gets to eat too");
      self.tummyFull = TRUE;  //setter access to own ivar
    }
     

Share This Page