Objective-C中的self

bob*_*obo 3 objective-c

在C++中是self不是完全可以互换this

它似乎与消息传递一起工作([ self sayHi ]可以在任何方法中工作).

我不太明白为什么我不能使用self来访问对象的私有成员(在下面的示例中,我显示我无法使用self.width)

#import <Foundation/Foundation.h>

// Write an Objective-C class
@interface Rectangle : NSObject
{
  int width ;
}

-(int)getWidth;
-(void)setWidth:(int)w;
-(void)sayHi;
-(void)sayHi:(NSString*)msg ;
@end

@implementation Rectangle

-(int)getWidth
{
  // <b>return self.width ; // ILLEGAL, but why?</b>
  // why can't I return self.width here?
  // why does it think that's a "method"?
  return width ;
}
-(void)setWidth:(int)w
{
  // <b>self.width = w ; // ILLEGAL</b>
  // again here, I CAN'T do self.width = w ;
  width = w ;
}
-(void)sayHi
{
  puts("hi");
}
-(void)sayHi:(NSString*)msg
{
  printf( "Hi, and %s\n", [ msg UTF8String ] ) ;
}

@end

int main (int argc, const char * argv[])
{
  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

  Rectangle* r = [ Rectangle alloc ] ;
  [ r sayHi ] ;
  [ r setWidth:5 ] ;
  printf( "width is %d\n", [ r getWidth ] ) ;

  [pool drain];
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

bbu*_*bum 12

其他答案几乎是正确的,但并不完全正确.

在Objective-C中,没有任何对象[保存为块,但这是一个非常特殊的情况]永远在堆栈中.因此,self.width没有意义.

但是,self->width 确实有效.因为self是对堆上分配的有效结构的引用,所以使用->运算符来获取成员变量是有意义的.

但是,在Objective-C的背景下,它通常也没有意义.也就是说,Objective-C通常假定保留封装的哲学.也就是说,您通常不会直接使用实例变量(内部状态)到达对象和muck.相反,您使用访问器来获取/设置状态.通过这样做,对象(和子类)可以根据需要自定义getter/setter行为.(这包括键值观察和键值编码等机制).

self.width恰好等同于[self width]或者[self setWidth: ...something...]是上述的后果.也就是说,.用于访问Objective-C类实例的成员的操作符没有以其他方式使用,并且可能作为属性访问的简写而被重载.

但是,属性访问调用getter/setter方法之间几乎没有区别.因此,点表示法与方法调用同义.


在代码的上下文中,实例变量可以在类实现中透明地访问,并且没有前缀.

因此,您通常会使用width = 5.0;而不是代替self.width = 5.0;.当然,后者确实等同于使用Objective-C 2.0的方法调用,原因如上所述.


Jor*_*eña 5

你不能使用,self.width因为它不是财产.self.width = w[self setWidth:w];Objective-C 2.0中引入的简写.尝试@property int width;在接口文件中添加上面的方法原型,并在行下的实现文件的顶部@implementation添加@synthesize width;.这应该允许你使用self.width,但它不再是一个私有变量.

你也可以使用@property (readonly) int width;,以生成宽度的"吸气剂"的方法,但我怀疑这是你想要的.有关您可以传递的更多选项@property,请查看此文档页面.

而且,像Cliff所说,getVar在Objective-C中不是惯例.相反,您只需使用要公开的变量的名称.该get前缀通常是用来当你回到某种形式的原始数据,据我知道.

  • Apple的Cocoa编码指南(http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingMethods.html#//apple_ref/doc/uid/20001282)声明`get`前缀只应在通过方法参数中给出的指针间接返回多个值时使用.例如,NSColor有一个名为`getRed:blue:green:alpha`的方法,它通过给定的`CGFloat`指针返回颜色的RGBA组件. (2认同)