在ObjC中自我是什么?我应该什么时候使用它?

时间:2021-11-15 22:59:57

What does self mean in Objective-C? When and where should I use it?Is it similar to this in Java?

在Objective-C中self是什么意思?我应该在何时何地使用它?它与Java类似吗?

6 个解决方案

#1


14  

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:

自我的最常见的用途之一是在类的初始化过程中。示例代码可能如下所示:

- (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


5  

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是对所有object - 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.

请注意,您只在object - 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运行时编程指南的Using Hidden Arguments部分。

#3


3  

Yes, it's exactly the same as "this" in Java - it points to the "current" object.

是的,它与Java中的“this”完全相同——它指向“当前”对象。

#4


2  

Two important notes:

两个重要的笔记:

  1. The class itself, e.g. UIView (I'm NOT talking about a UIView object) is itself an object, and there is a self associated with it. So for example, you can reference self in a class method like this:

    类本身,例如,UIView(我不是说UIView对象)本身就是一个对象,有一个与它相关联的自我。例如,你可以在类方法中引用self

    // This works+(void) showYourself { [self performSelector: @selector(makeTheMostOfYourself)]; }// Class method!+(void) makeTheMostOfYourself { }
  2. 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


0  

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

答:使用自

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中的每个消息(单个异常:到super的消息)都会导致在子类中执行一个方法:

@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)

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.

self指向什么?它指向发送消息的对象,从而导致当前方法的执行。

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 -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


-1  

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


14  

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:

自我的最常见的用途之一是在类的初始化过程中。示例代码可能如下所示:

- (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


5  

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是对所有object - 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.

请注意,您只在object - 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运行时编程指南的Using Hidden Arguments部分。

#3


3  

Yes, it's exactly the same as "this" in Java - it points to the "current" object.

是的,它与Java中的“this”完全相同——它指向“当前”对象。

#4


2  

Two important notes:

两个重要的笔记:

  1. The class itself, e.g. UIView (I'm NOT talking about a UIView object) is itself an object, and there is a self associated with it. So for example, you can reference self in a class method like this:

    类本身,例如,UIView(我不是说UIView对象)本身就是一个对象,有一个与它相关联的自我。例如,你可以在类方法中引用self

    // This works+(void) showYourself { [self performSelector: @selector(makeTheMostOfYourself)]; }// Class method!+(void) makeTheMostOfYourself { }
  2. 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


0  

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

答:使用自

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中的每个消息(单个异常:到super的消息)都会导致在子类中执行一个方法:

@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)

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.

self指向什么?它指向发送消息的对象,从而导致当前方法的执行。

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 -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


-1  

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类似。