I do not understand the local variable self


#1

Dear Bignerdranch users,

I do not understand the local variable self how it is explained in the book.
Can someone give an simple explaination to me from which I can understand the use of the self variable.

Thanks in advance.

Kind regards,

Mizuhodb


#2

Yes, this entire chapter was annoyingly vague. I am sure the information is a refresher to those who already understand the concept but for those that don’t it’s rather abstract. For one, the syntax for implementing accessors in the .m file wasn’t explained enough and the SELF method was explained but never was the, “why do we need SELF”, question answered. I’ve gone through chapters 1-17 without to much problems but 18 felt like we had to understand by doing. Which is fine but takes a long time.


#3

looks for more definitions in other sites
for example stack overflow.

Even though BNR Rocks! with its explanations ; ))


#4

self is not hard to understand if you keep the following facts in mind.

All methods operate on an object.

Every method (except init… methods) of a class has a hidden argument named self, which points to the object the method operates on.

Here are the three key facts you should know about self:

  • In a class method, self points to the class object; there is only one class object.

  • In an instance method, self points to an object, that is, an instance of the class; there can be many instances.

  • An object can send itself a message by simply sending the message to self.

Look at the following all-in-one example:

//  main.m

#import <Foundation/Foundation.h>

// A simple class
@interface FooBar : NSObject

- (instancetype)initWithName:(NSString *)name;

+ (void)paintWhite;
- (void)paintGreen;
- (void)paintYellow;
- (void)paintWhatever;

@end

int main (int argc, const char * argv[])
{
    @autoreleasepool {
        FooBar *fooBar1 = [[FooBar alloc] initWithName:@"fooBar1"];
        FooBar *fooBar2 = [[FooBar alloc] initWithName:@"fooBar2"];
        FooBar *fooBar3 = [[FooBar alloc] initWithName:@"fooBar3"];

        // Print the address of the class object and paint it...
        printf ("%s: class_obj = %p\n", __func__, [FooBar class]);
        [FooBar paintWhite];
        printf ("\n");
        
        // Print the address of fooBar1 and paint it...
        printf ("%s: fooBar1 = %p class_obj = %p\n", __func__, fooBar1, [FooBar class]);
        [fooBar1 paintGreen];
        printf ("\n");
        
        // Print the address of fooBar2 and paint it...
        printf ("%s: fooBar2 = %p class_obj = %p\n", __func__, fooBar2, [FooBar class]);
        [fooBar2 paintYellow];
        printf ("\n");
        
        // Print the address of fooBar3 and paint it...
        printf ("%s: fooBar3 = %p class_obj = %p\n", __func__, fooBar3, [FooBar class]);
        [fooBar3 paintYellow];
        printf ("\n");
        
        // Get it to send a message to itself...
        [fooBar3 paintWhatever];
        printf ("\n");
    }
    return 0;
}

@implementation FooBar
{
    NSString *_name;
}

- (instancetype)initWithName:(NSString *)name
{
    self = [super init];
    if (self) {
        _name = [name copy];
    }
    return self;
}

+ (void)paintWhite
{
    printf ("%s: self = %p class_obj = %p\n", __func__, self, [FooBar class]);
}

- (void)paintGreen
{
    printf ("%s: %s self = %p class_obj = %p\n", __func__, _name.UTF8String, self, [FooBar class]);
}

- (void)paintYellow
{
    printf ("%s: %s self = %p class_obj = %p\n", __func__, _name.UTF8String, self, [FooBar class]);
}

- (void)paintWhatever
{
    printf ("%s: %s self = %p class_obj = %p\n", __func__, _name.UTF8String, self, [FooBar class]);
    [self paintGreen];
}

@end

If you build and run the above example, you should see output that looks like this:

main: class_obj = 0x100002220
+[FooBar paintWhite]: self = 0x100002220 class_obj = 0x100002220

main: fooBar1 = 0x1001096d0 class_obj = 0x100002220
-[FooBar paintGreen]: fooBar1 self = 0x1001096d0 class_obj = 0x100002220

main: fooBar2 = 0x1001096e0 class_obj = 0x100002220
-[FooBar paintYellow]: fooBar2 self = 0x1001096e0 class_obj = 0x100002220

main: fooBar3 = 0x10010a770 class_obj = 0x100002220
-[FooBar paintYellow]: fooBar3 self = 0x10010a770 class_obj = 0x100002220

-[FooBar paintWhatever]: fooBar3 self = 0x10010a770 class_obj = 0x100002220
-[FooBar paintGreen]: fooBar3 self = 0x10010a770 class_obj = 0x100002220

Now you should carefully examine the above output and spot those three key facts about self.

[Accelerate your learning and become a competent programmer faster than you can imagine: pretty-function.org]