What does self
mean in Objective-C? When and where should I use it?Is it similar to this
in Java?
Objective-C中的自我意味着什么?我应该在何时何地使用它?它与Java中的相似吗?
6 个解决方案
#1
self
refers to the instance of the current class that you are working in, and yes, it is analagous to this
in Java.
self指的是您正在使用的当前类的实例,是的,它在Java中与此类似。
You use it if you want to perform an operation on the current instance of that class. For example, if you are writing an instance method on a class, and you want to call a method on that same instance to do something or retrieve some data, you would use self
:
如果要对该类的当前实例执行操作,请使用它。例如,如果要在类上编写实例方法,并且要在同一实例上调用方法来执行某些操作或检索某些数据,则可以使用self:
int value = [self returnSomeInteger];
This is also often used for accessor methods on an instance (i.e. setters and getters) especially with setter methods, if they implement extra functionality rather than just setting the value of an instance variable, so that you do not have to repeat that code over and over when you want to set the value of that variable, for example:
这通常也用于实例上的访问器方法(即setter和getter),特别是使用setter方法,如果它们实现额外的功能而不是仅设置实例变量的值,那么你就不必重复代码当您想要设置该变量的值时,例如:
[self setSomeVariable:newValue];
One of the most common uses of self
is during initialization of a class. Sample code might look like:
self的最常见用途之一是在类的初始化期间。示例代码可能如下所示:
- (id)init{ self = [super init]; if(self!=nil) { //Do stuff, such as initializing instance variables } return self;}
This invokes the superclass's (via super
) initializer, which is how chained initialization occurs up the class hierarchy. The returned value is then set to self
, however, because the superclass's initializer could return a different object than the superclass.
这将调用超类(通过超级)初始化程序,这是在类层次结构中进行链式初始化的方式。然后,返回的值设置为self,因为超类的初始值设定项可以返回与超类不同的对象。
#2
self
is an implied argument to all Obj-C methods that contains a pointer to the current object in instance methods, and a pointer to the current class in class methods.
self是所有Obj-C方法的隐含参数,它包含指向实例方法中当前对象的指针,以及指向类方法中当前类的指针。
Another implied argument is _cmd
, which is the selector that was sent to the method.
另一个隐含的参数是_cmd,它是发送给方法的选择器。
Please be aware that you only get self
and _cmd
in Obj-C methods. If you declare a C(++) method, for instance as a callback from some C library, you won't get self or cmd.
请注意,您只能使用Obj-C方法获得self和_cmd。如果您声明一个C(++)方法,例如作为来自某个C库的回调,您将不会获得self或cmd。
For more information, see the Using Hidden Arguments section of the Objective-C Runtime Programming guide.
有关更多信息,请参阅Objective-C运行时编程指南的使用隐藏参数部分。
#3
Yes, it's exactly the same as "this" in Java - it points to the "current" object.
是的,它与Java中的“this”完全相同 - 它指向“当前”对象。
#4
Two important notes:
两个重要说明:
-
The class itself, e.g.
UIView
(I'm NOT talking about aUIView
object) is itself an object, and there is aself
associated with it. So for example, you can referenceself
in a class method like this:班级本身,例如UIView(我不是在谈论UIView对象)本身就是一个对象,并且有一个与之相关的自我。例如,您可以在类方法中引用self,如下所示:
// This works+(void) showYourself { [self performSelector: @selector(makeTheMostOfYourself)]; }// Class method!+(void) makeTheMostOfYourself { }
-
Note that the compiler does NOT raise any warnings or errors, even if the
self
you mean to reference is an object and not a class. It is VERY easy to cause crashes this way, for example:请注意,编译器不会引发任何警告或错误,即使您要引用的self是一个对象而不是一个类。以这种方式导致崩溃非常容易,例如:
// This will crash!+(void) showYourself { [self performSelector: @selector(makeTheMostOfYourself)]; }// Object method!-(void) makeTheMostOfYourself { }// This will crash too!-(void) showYourself2 { [self performSelector: @selector(makeTheMostOfYourself2)]; }// Class method!+(void) makeTheMostOfYourself2 { }
Sadly, this makes class methods a bit harder to use, which is unfortunate because they are a valuable tool for encapsulation through information hiding. Just be careful.
遗憾的是,这使得类方法更难以使用,这是不幸的,因为它们是通过信息隐藏进行封装的有用工具。小心点
#5
Wow, that many half-correct answers and misleading hints. This let me answer the Q even there is a accepted answer for years:
哇,这很多半正确的答案和误导性的暗示。这让我回答问题,即使多年来有一个公认的答案:
First of all: It is really hard to compare a concept of messaging/calling in the context of an early binding, static typing language as Java with a late binding, dynamically typing languages as Objective-C. At one point this will break. I would say: No, this is not similiar, since the typing and dispatching concepts of both language are fundamental different so nothing can be similar to the other one. However, …
首先:将早期绑定,静态类型语言作为Java与后期绑定,动态类型语言作为Objective-C的上下文中的消息传递/调用概念进行比较真的很难。有一次这会破裂。我会说:不,这不是类似的,因为两种语言的打字和调度概念是根本不同的,所以没有什么可以与另一种相似。但是,......
Then we should differ between the "two sides" of self
.
那么我们应该区分自我的“双方”。
A. Using self
A.使用自我
When you use it in a message, it is simply an object reference as any other:
当您在消息中使用它时,它只是一个对象引用,如同任何其他:
[self doSomething];[anotherObject doSomething];
Technically both lines works identically (accept of having a different receiver, of course). This especially means, that the first line does not lead to an execution of a method inside the class of self
, because self
does not necessarily refer to "that class". As every message inside Objective-C (single exception: messages to super
)this can lead to the execution of a method in a subclass:
从技术上讲,两条线的工作方式相同(当然接受不同的接收器)。这尤其意味着,第一行不会导致在self类中执行一个方法,因为self不一定会引用“那个类”。作为Objective-C中的每个消息(单个异常:消息到超级),这可能导致在子类中执行方法:
@interface A : NSObject- (void)doSomething;- (void)doAnotherThing;@end@implementation - (void)doSomething{ [self doAntoherThing];}- (void)doAnotherThing{ NSLog( @"A" );}@interface B : A- (void)doSomething; // Not necessary, simply as a marker@end@implementation B- (void)doAnotherThing{ NSLog( @"B" );}
In a code like this
在像这样的代码中
B *b = [B new;][b doSomething];
The line
[self doAnotherThing];
in class A
will lead to the execution of -doAnotherThing
(B
), because messages to self
are late bound as every other message. The result on the console will b "B", not "A". Using self
as a receiver you should not think of a single special rule. There is completely none.
在A类中将导致-doAnotherThing(B)的执行,因为到self的消息被后期绑定为每个其他消息。控制台上的结果将是“B”,而不是“A”。使用self作为接收者,你不应该想到一个特殊的规则。完全没有。
(And the above example is a very good example for using self
in class methods, because the same situation can occur on class methods. Using the class itself breaks polymorphism, what is one of the worst idea at all in OOP. DO use self
in class methods, too.)
(以上示例是在类方法中使用self的一个非常好的示例,因为类方法可能会出现相同的情况。使用类本身会破坏多态性,这在OOP中是最糟糕的想法之一。请使用self in类方法也。)
B. Getting self
B.获得自我
What is self
pointing to? It points to the object to whom the message is sent that caused the execution of the current method.
什么是自我指向?它指向发送消息的对象导致执行当前方法。
Having …
…[someObject doSomething]… // some object is a reference to an instance object
… as a message, a method is called, in the most simple case …
...作为一个消息,一个方法被调用,在最简单的情况下......
- (void)doSomething{ … }
In such a case, self
can point to an instance of the class, the method belongs to. And it can point to an instance of a subclass, the method belongs to, too. You don't know. (And this information is preserved using self
to send a message as explained above.)
在这种情况下,self可以指向该类的实例,该方法属于。并且它可以指向子类的实例,该方法也属于。你不知道。 (并且使用self保存此信息以发送消息,如上所述。)
If the message is sent to a class object, self
points to the class object, that was the receiver of the message. This is completely analogous. Therefore it is possible that self
points to a subclass object:
如果消息被发送到类对象,则self指向类对象,即消息的接收者。这完全是类似的。因此,self可能指向子类对象:
@interface A : NSObject+ (void)doSomething;+ (void)doAnotherThing;@end@implementation + (void)doSomething{ [self doAntoherThing];}+ (void)doAnotherThing{ NSLog( @"A" );}@interface B : A- (void)doSomething; // Not necessary, simply as a marker@end@implementation B+ (void)doAnotherThing{ NSLog( @"B" );}
Having this classes
有这个课程
…[A doSomething]…
self
inside -doSomething
(A
) points to the class object of B
. Therefore [self doAnotherThing]
of B
(!) is executed. This is clearly different from
self inside -doSomething(A)指向B的类对象。因此执行B(!)的[self doAnotherThing]。这明显不同于
+ (void)doSomething{ [A doAntoherThing];}
The latter version causes relevant harm to the principles of OOP.
后一版本对OOP原则造成相关损害。
As a side note it is possible that self
inside a class method of a root class points to an instance object of the root class or any subclass. You have to keep this in mind, when writing categories on NSObject
.
作为旁注,根类的类方法中的self可能指向根类或任何子类的实例对象。在NSObject上编写类别时,您必须牢记这一点。
#6
self is an object pointer to the current instances dispatch table. It is an implicit first argument to every member function of an object, and is assigned when that function is called.
self是指向当前实例调度表的对象指针。它是对象的每个成员函数的隐式第一个参数,并在调用该函数时分配。
In functions like init, you need to be careful that when you call the super class init you reassign self to be the return value as the super class init may redefine what self points to.
在像init这样的函数中,你需要注意当你调用超类init时,你将self重新分配为返回值,因为超类init可能会重新定义self指向的内容。
super is similar to self except it points to the superclass dispatch table.
super类似于self,除了它指向超类调度表。
#1
self
refers to the instance of the current class that you are working in, and yes, it is analagous to this
in Java.
self指的是您正在使用的当前类的实例,是的,它在Java中与此类似。
You use it if you want to perform an operation on the current instance of that class. For example, if you are writing an instance method on a class, and you want to call a method on that same instance to do something or retrieve some data, you would use self
:
如果要对该类的当前实例执行操作,请使用它。例如,如果要在类上编写实例方法,并且要在同一实例上调用方法来执行某些操作或检索某些数据,则可以使用self:
int value = [self returnSomeInteger];
This is also often used for accessor methods on an instance (i.e. setters and getters) especially with setter methods, if they implement extra functionality rather than just setting the value of an instance variable, so that you do not have to repeat that code over and over when you want to set the value of that variable, for example:
这通常也用于实例上的访问器方法(即setter和getter),特别是使用setter方法,如果它们实现额外的功能而不是仅设置实例变量的值,那么你就不必重复代码当您想要设置该变量的值时,例如:
[self setSomeVariable:newValue];
One of the most common uses of self
is during initialization of a class. Sample code might look like:
self的最常见用途之一是在类的初始化期间。示例代码可能如下所示:
- (id)init{ self = [super init]; if(self!=nil) { //Do stuff, such as initializing instance variables } return self;}
This invokes the superclass's (via super
) initializer, which is how chained initialization occurs up the class hierarchy. The returned value is then set to self
, however, because the superclass's initializer could return a different object than the superclass.
这将调用超类(通过超级)初始化程序,这是在类层次结构中进行链式初始化的方式。然后,返回的值设置为self,因为超类的初始值设定项可以返回与超类不同的对象。
#2
self
is an implied argument to all Obj-C methods that contains a pointer to the current object in instance methods, and a pointer to the current class in class methods.
self是所有Obj-C方法的隐含参数,它包含指向实例方法中当前对象的指针,以及指向类方法中当前类的指针。
Another implied argument is _cmd
, which is the selector that was sent to the method.
另一个隐含的参数是_cmd,它是发送给方法的选择器。
Please be aware that you only get self
and _cmd
in Obj-C methods. If you declare a C(++) method, for instance as a callback from some C library, you won't get self or cmd.
请注意,您只能使用Obj-C方法获得self和_cmd。如果您声明一个C(++)方法,例如作为来自某个C库的回调,您将不会获得self或cmd。
For more information, see the Using Hidden Arguments section of the Objective-C Runtime Programming guide.
有关更多信息,请参阅Objective-C运行时编程指南的使用隐藏参数部分。
#3
Yes, it's exactly the same as "this" in Java - it points to the "current" object.
是的,它与Java中的“this”完全相同 - 它指向“当前”对象。
#4
Two important notes:
两个重要说明:
-
The class itself, e.g.
UIView
(I'm NOT talking about aUIView
object) is itself an object, and there is aself
associated with it. So for example, you can referenceself
in a class method like this:班级本身,例如UIView(我不是在谈论UIView对象)本身就是一个对象,并且有一个与之相关的自我。例如,您可以在类方法中引用self,如下所示:
// This works+(void) showYourself { [self performSelector: @selector(makeTheMostOfYourself)]; }// Class method!+(void) makeTheMostOfYourself { }
-
Note that the compiler does NOT raise any warnings or errors, even if the
self
you mean to reference is an object and not a class. It is VERY easy to cause crashes this way, for example:请注意,编译器不会引发任何警告或错误,即使您要引用的self是一个对象而不是一个类。以这种方式导致崩溃非常容易,例如:
// This will crash!+(void) showYourself { [self performSelector: @selector(makeTheMostOfYourself)]; }// Object method!-(void) makeTheMostOfYourself { }// This will crash too!-(void) showYourself2 { [self performSelector: @selector(makeTheMostOfYourself2)]; }// Class method!+(void) makeTheMostOfYourself2 { }
Sadly, this makes class methods a bit harder to use, which is unfortunate because they are a valuable tool for encapsulation through information hiding. Just be careful.
遗憾的是,这使得类方法更难以使用,这是不幸的,因为它们是通过信息隐藏进行封装的有用工具。小心点
#5
Wow, that many half-correct answers and misleading hints. This let me answer the Q even there is a accepted answer for years:
哇,这很多半正确的答案和误导性的暗示。这让我回答问题,即使多年来有一个公认的答案:
First of all: It is really hard to compare a concept of messaging/calling in the context of an early binding, static typing language as Java with a late binding, dynamically typing languages as Objective-C. At one point this will break. I would say: No, this is not similiar, since the typing and dispatching concepts of both language are fundamental different so nothing can be similar to the other one. However, …
首先:将早期绑定,静态类型语言作为Java与后期绑定,动态类型语言作为Objective-C的上下文中的消息传递/调用概念进行比较真的很难。有一次这会破裂。我会说:不,这不是类似的,因为两种语言的打字和调度概念是根本不同的,所以没有什么可以与另一种相似。但是,......
Then we should differ between the "two sides" of self
.
那么我们应该区分自我的“双方”。
A. Using self
A.使用自我
When you use it in a message, it is simply an object reference as any other:
当您在消息中使用它时,它只是一个对象引用,如同任何其他:
[self doSomething];[anotherObject doSomething];
Technically both lines works identically (accept of having a different receiver, of course). This especially means, that the first line does not lead to an execution of a method inside the class of self
, because self
does not necessarily refer to "that class". As every message inside Objective-C (single exception: messages to super
)this can lead to the execution of a method in a subclass:
从技术上讲,两条线的工作方式相同(当然接受不同的接收器)。这尤其意味着,第一行不会导致在self类中执行一个方法,因为self不一定会引用“那个类”。作为Objective-C中的每个消息(单个异常:消息到超级),这可能导致在子类中执行方法:
@interface A : NSObject- (void)doSomething;- (void)doAnotherThing;@end@implementation - (void)doSomething{ [self doAntoherThing];}- (void)doAnotherThing{ NSLog( @"A" );}@interface B : A- (void)doSomething; // Not necessary, simply as a marker@end@implementation B- (void)doAnotherThing{ NSLog( @"B" );}
In a code like this
在像这样的代码中
B *b = [B new;][b doSomething];
The line
[self doAnotherThing];
in class A
will lead to the execution of -doAnotherThing
(B
), because messages to self
are late bound as every other message. The result on the console will b "B", not "A". Using self
as a receiver you should not think of a single special rule. There is completely none.
在A类中将导致-doAnotherThing(B)的执行,因为到self的消息被后期绑定为每个其他消息。控制台上的结果将是“B”,而不是“A”。使用self作为接收者,你不应该想到一个特殊的规则。完全没有。
(And the above example is a very good example for using self
in class methods, because the same situation can occur on class methods. Using the class itself breaks polymorphism, what is one of the worst idea at all in OOP. DO use self
in class methods, too.)
(以上示例是在类方法中使用self的一个非常好的示例,因为类方法可能会出现相同的情况。使用类本身会破坏多态性,这在OOP中是最糟糕的想法之一。请使用self in类方法也。)
B. Getting self
B.获得自我
What is self
pointing to? It points to the object to whom the message is sent that caused the execution of the current method.
什么是自我指向?它指向发送消息的对象导致执行当前方法。
Having …
…[someObject doSomething]… // some object is a reference to an instance object
… as a message, a method is called, in the most simple case …
...作为一个消息,一个方法被调用,在最简单的情况下......
- (void)doSomething{ … }
In such a case, self
can point to an instance of the class, the method belongs to. And it can point to an instance of a subclass, the method belongs to, too. You don't know. (And this information is preserved using self
to send a message as explained above.)
在这种情况下,self可以指向该类的实例,该方法属于。并且它可以指向子类的实例,该方法也属于。你不知道。 (并且使用self保存此信息以发送消息,如上所述。)
If the message is sent to a class object, self
points to the class object, that was the receiver of the message. This is completely analogous. Therefore it is possible that self
points to a subclass object:
如果消息被发送到类对象,则self指向类对象,即消息的接收者。这完全是类似的。因此,self可能指向子类对象:
@interface A : NSObject+ (void)doSomething;+ (void)doAnotherThing;@end@implementation + (void)doSomething{ [self doAntoherThing];}+ (void)doAnotherThing{ NSLog( @"A" );}@interface B : A- (void)doSomething; // Not necessary, simply as a marker@end@implementation B+ (void)doAnotherThing{ NSLog( @"B" );}
Having this classes
有这个课程
…[A doSomething]…
self
inside -doSomething
(A
) points to the class object of B
. Therefore [self doAnotherThing]
of B
(!) is executed. This is clearly different from
self inside -doSomething(A)指向B的类对象。因此执行B(!)的[self doAnotherThing]。这明显不同于
+ (void)doSomething{ [A doAntoherThing];}
The latter version causes relevant harm to the principles of OOP.
后一版本对OOP原则造成相关损害。
As a side note it is possible that self
inside a class method of a root class points to an instance object of the root class or any subclass. You have to keep this in mind, when writing categories on NSObject
.
作为旁注,根类的类方法中的self可能指向根类或任何子类的实例对象。在NSObject上编写类别时,您必须牢记这一点。
#6
self is an object pointer to the current instances dispatch table. It is an implicit first argument to every member function of an object, and is assigned when that function is called.
self是指向当前实例调度表的对象指针。它是对象的每个成员函数的隐式第一个参数,并在调用该函数时分配。
In functions like init, you need to be careful that when you call the super class init you reassign self to be the return value as the super class init may redefine what self points to.
在像init这样的函数中,你需要注意当你调用超类init时,你将self重新分配为返回值,因为超类init可能会重新定义self指向的内容。
super is similar to self except it points to the superclass dispatch table.
super类似于self,除了它指向超类调度表。