Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialScott Muhs
2,621 Pointsself
Can someone explain to me why we put self at the beginning of this action message?
3 Answers
Mike Baxter
4,442 PointsHmmm... I don't think it's really necessary. (Have you tried it without the reference to self?)
The whole purpose of using self is to allow room for subclassing. Suppose I make a class called MusicSetList and it only has a list of song names contained in some array. That's all, just NSStrings in an array. But suppose someone later wants to borrow my MusicSetList class and modify it to contain another array—maybe it's a bunch of mp3 links for those songs, or sheet music, whatever. They subclass MusicSetList and call it something like MusicListWithAudio. Now that whole "self" thing becomes really important—which object is it referring to, the MusicSetList or the MusicListWithAudio. By calling "self", it alleviates the issue of having to determine which one to call.
Maybe a good way to see this is if MusicListWithAudio contains a method called (NSArray)mp3List that returns an array of all the mp3 links. If I try to call this method on my superclass, MusicSetList, it will give me an unrecognized selector error. But if I just call "self", the compiler figures out that I'm really referring to the MusicListWithAudio subclass.
I think I'm missing something major here though in terms of importance of subclassing. (I know it's an area I need to review.) But that's the big idea with "self" is so you can set yourself up to subclass properly.
In the case you're talking about, I don't think it's necessary to call "self" since "self" should be implicit for that class.
Marek Hrusovsky
4,217 Pointsself => current instance of object of this class. When you create new object in "init" method you assign it to self. It helps you to access your created object within other methods. For the case you are asking: action has been called and there is an object that process/handles the answer. Within Interface Builder of Xcode you can't see it but if you create action programmatically it would look like this:
[button addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];
Again the self refers to instance of object that was created in the same class.
@implementation MyClass
-(instancetype)init {
self = [super init];
if (self) { //your initialization }
return self;
} @end .
Marek Hrusovsky
4,217 PointsObjective-C is a message sending language. So you always need to know to whom you are sending the message (self or other instantiated object). So self can't be omitted.
[self clickedOnAbutton];
translates into
objc_msgSend(self, @selector(clickedOnAbutton));
Mike Baxter
4,442 PointsSure, but you're not asking the overall class to perform some method, so you don't need to call self. In the OP's question (from the video), it's asking an IBOutlet (rather than self) to perform a method (like the "setText" accessor). So I agree that you can't omit the receiver of the message, but in this case, it's the question of which of the following is more appropriate:
[[self myTextField] setText:@"random"];
or
[myTextField setText:@"random"];
Marek Hrusovsky
4,217 PointsMike Baxter You were right that it is not necessary. I forgot about instance variables. However I do not recommend you direct accessing to instance variables in other places than "init". You loose all benefits of objective-C e.g. KVO ...
@interface MyClass { NSString *_test; }
@end.
@implementation MyClass @synthesize test = _test;
-(instancetype)init {
self = [super init];
if (self) { _test =@"ddd"; }
return self;
}
-(void)uglyMethod { //other parts of program might be observing but they will not know about change _test = @"New text"; //other parts of program might be observing and they get notification self.text = @"New text"; }
@end .
Marek Hrusovsky
4,217 PointsMarek Hrusovsky
4,217 PointsObjective-C is a message sending language. So you always need to know to whom you are sending the message (self or other instantiated object). So self can't be omitted.
Mike Baxter
4,442 PointsMike Baxter
4,442 PointsBut Marek Hrusovsky , self should be implicit within the scope of the class. At least, the book I learned iOS from ("iOS Programming 3rd Ed." by Aaron Hillegass) doesn't ever reference variables in the way the OP described. (There's also a Stackoverflow post where someone says things changed with ARC, so you never have to use "self." to reference a local variable.)