类属性mVar和实例变量self.mVar之间的区别

mr-*_*-sk 4 oop iphone objective-c self core-foundation

我对于通过self访问实例变量或仅通过名称(在类中工作时)之间的区别感到困惑.

例如,参加这个课程:

//In .h file:
@interface Register : NSObject {
    NSString *mName;
}

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

//In .m file:
- (id) initWithName:(NSString *)name
{
    if (self == [super init])
    {
        mName = name;
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)

通过访问实例变量之间的区别是什么

self.mName = name;
Run Code Online (Sandbox Code Playgroud)

VS

mName = name;
Run Code Online (Sandbox Code Playgroud)

哪个不是@property而且不是@ sythenize'd.

说这是这个,但是这个例子:

//In .h file:
@interface Manange_My_ViewsViewController : UIViewController { 
    IBOutlet UILabel *countLabel;
}

@property (nonatomic, retain) IBOutlet UILabel *countLabel;

//In .m file:
@synthesize countLabel;

- (void) updateLabel:(NSUInteger)count
{
    countLabel.text = [NSString stringWithFormat:@"%d", count];
}
Run Code Online (Sandbox Code Playgroud)

但是我说访问countLabel:

self.countLabel
Run Code Online (Sandbox Code Playgroud)

有什么区别?

编辑:每个用户答案的​​第三个例子:说它iVar不是IBOutlet:

//In .h file:
@interface Fake : NSObject {
    NSString *mVar;
}
@property (nonatomic, retain) NSString *mVar;

//In .m file:
 @synthesize mVar;

 mVar = @"";
Run Code Online (Sandbox Code Playgroud)

VS

 self.mVar = @"";
Run Code Online (Sandbox Code Playgroud)

或者它是相同的 - 在第一个我们访问实际的实例变量,在第二个我们实际上通过自动创建的setter(通过@synthesize)?

谢谢大家!

编辑:更新以响应Peter Hosey ......

所以你认为mVarName的约定很糟糕?我从C++时代就开始了.

但是当你这样做的情况呢?

-(void) someMethod:(int) x
{
    x = x;
}
Run Code Online (Sandbox Code Playgroud)

你不能这样做(说'x'也是一个类变量)

但你可以这样做:

-(void) someMethod:(int) x
{
    mX = x;
}
Run Code Online (Sandbox Code Playgroud)

但你说它做得更好:

-(void) someMethod:(int) x
{
    self.x = x;
}
Run Code Online (Sandbox Code Playgroud)

Pet*_*sey 7

通过访问实例变量之间的区别是什么

self.mName = name;
Run Code Online (Sandbox Code Playgroud)

VS

mName = name;
Run Code Online (Sandbox Code Playgroud)

第一个是属性访问语法.它转换为对象的访问者消息(在本例中self).也就是说,该语句隐式转换为此消息表达式语句:

[self setMName:name];
Run Code Online (Sandbox Code Playgroud)

(像这样的尴尬访问者名称是"mName"是属性的一个糟糕名称的原因.有一个属性声明语法可以解决这个问题,让你命名属性"name"和你的实例变量"mName"并将一个映射到另一个.)

第二个示例直接访问实例变量 - 无访问者消息.

哪个不是@property而且不是@ sythenize'd.

说这是这个,...

如果没有mName为类声明名为" "的属性,则不能使用属性访问语法在该类的实例上按该名称访问属性.

无论您是合成访问器,将它们手动传递给超类@dynamic,还是自己定义它们都无关紧要.这就是对象如何响应访问者消息,但编译器生成的访问者消息也没有什么不同(因为属性访问可能很容易来自类外部而不是来自内部).

说它iVar不是IBOutlet:

那没关系.IBOutlet仅对IB有意义.其他一切都不在乎.

事实上,IBOutlet目前只是一个扩展到零的宏.在对代码进行预处理之后,单词"IBOutlet"不再存在,因此编译器永远不会看到它.除了IB之外,这对于任何事情都没有什么区别:完全没有.

编辑以回答问题编辑

我说mName作为属性名称是坏的,因为它后面的访问者名称.实例变量的名称是一个单独的问题,特别是因为属性和ivar不必具有相同的名称.

对于一个变量,无论是一个实例变量或局部变量的选择namem_namemName纯粹是一种风格的选择.

someMethod:通常是访问者,setX:.在该方法中self.x = x,即[self setX:x]导致无限递归.所以不要这样做.

someMethod:不是访问者(或initdealloc)时,使用该属性就好了,通常更可取.但是,在这种情况下,您不可能给它的一个参数赋予与实例变量相同的名称.如果出现这种情况,请更具体地命名局部变量,因为其目的更具体.这也是一个风格问题.

当它是访问者时,我将局部变量newX命名为,将实例变量命名为与属性相同x.这是我个人的风格; 正如我所说,命名属性x,ivar mX和局部变量x也很好(除了这个例子的过度简洁).