类属性mVar和实例变量self.mVar之间的区别 [英] Difference between class property mVar and instance variable self.mVar

查看:121
本文介绍了类属性mVar和实例变量self.mVar之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于通过self或按名称访问实例变量(在类中进行操作)之间的区别,我有些困惑.

I am some what confused as to the difference between accessing an instance variable via self or just by name (when working inside the class).

例如,参加此类:

//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;
}

通过访问访问实例变量有什么区别

What's the difference between accessing the instance variable via

self.mName = name;

vs

mName = name;

这不是@property,也不是@sythenize.

Which isn't a @property and is not @sythenize'd.

根据这个示例,就是这样:

Say it is this though, per this example:

//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];
}

但是说我以以下方式访问countLabel:

But say I accessed countLabel as:

self.countLabel

有什么区别?

每个用户答案的​​第三个示例: 假设iVar不是IBOutlet:

Third example per users' answer: Say it the iVar wasn't an IBOutlet:

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

//In .m file:
 @synthesize mVar;

 mVar = @"";

VS

 self.mVar = @"";

还是一样-在第一个实例中,我们访问实际的实例变量,在第二个实例中,我们实际通过自动创建的setter(通过@synthesize)进行操作?

Or is it the same - that in the first we are accessing the actual instance variable and in the second we're actually going through the auto created setter (via @synthesize)?

谢谢!

更新以响应Peter Hosey ...

Update in response to Peter Hosey ...

那么您认为mVarName的约定不好吗?我是从C ++时代那来的.

So your thinking the convention of mVarName is bad? I took that from my C++ days.

那你怎么办呢?

-(void) someMethod:(int) x
{
    x = x;
}

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

You can't do that (Say 'x' is also a class variable)

但是您可以这样做:

-(void) someMethod:(int) x
{
    mX = x;
}

但是您最好说一遍:

-(void) someMethod:(int) x
{
    self.x = x;
}

推荐答案

通过访问访问实例变量有什么区别

What's the difference between accessing the instance variable via

self.mName = name;

vs

mName = name;

第一个是属性访问语法.它转换为对象的访问者消息(在这种情况下为self).也就是说,该语句隐式转换为以下消息表达语句:

The first is property access syntax. It translates to an accessor message to the object (in this case, self). That is, that statement implicitly translates to this message expression statement:

[self setMName:name];

(这样的笨拙的访问器名称就是为什么"mName"是属性的较差名称的原因.有一种属性声明语法可以解决该问题,让您将属性命名为"name",并将实例变量"mName"命名为一个到另一个.)

(Awkward accessor names like that are why "mName" is a poor name for a property. There is property declaration syntax to work around that, letting you name the property "name" and your instance variable "mName" and map one to the other.)

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

The second example directly accesses the instance variable—no accessor message.

这不是@property,也不是@sythenize.

Which isn't a @property and is not @sythenize'd.

不过就是这个,……

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

If no property named "mName" is declared for a class, then you can't use property access syntax to access a property by that name on an instance of that class.

合成访问器,使用@dynamic将它们手动传递给超类还是自己定义它们都没有关系.这就是对象如何响应访问者消息的方式,但是编译器生成的访问者消息也没有什么不同(因为属性访问可以像从类内部一样容易地从类外部进行).

And it doesn't matter whether you synthesize the accessors, hand-wave them to a superclass with @dynamic, or define them yourself. That's how the object will respond to the accessor message, but the accessor message the compiler generates will be no different (since a property access could just as easily come from outside the class as from inside it).

说iVar不是IBOutlet:

Say it the iVar wasn't an IBOutlet:

没关系. IBOutlet仅对IB意味着任何意义.其他一切都不在乎.

That doesn't matter. IBOutlet only means anything to IB. Everything else doesn't care.

实际上,IBOutlet当前只是一个扩展为空的宏.在对代码进行预处理之后,"IBOutlet"一词不再存在,因此编译器将永远不会看到它.这对除IB以外的任何事物都几乎没有什么影响:完全没有.

In fact, IBOutlet is currently just a macro that expands to nothing. After your code gets preprocessed, the word "IBOutlet" is no longer there, so the compiler never sees it. That's how little a difference it makes to anything but IB: None at all.

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

I said mName is bad as a property name, because of the accessor names that follow from it. The name of an instance variable is a separate issue, particularly since the property and ivar don't have to have the same name.

对于变量,无论是实例变量还是局部变量,选择namem_namemName纯粹是一种样式选择.

For a variable, be it an instance variable or a local variable, the choice of name or m_name or mName is purely a style choice.

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

someMethod: is generally the accessor, setX:. Within that method, self.x = x, which is [self setX:x], causes infinite recursion. So don't do that.

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

When someMethod: isn't the accessor (or init or dealloc), using the property is just fine and generally preferable. However, in that case, you're not likely to give one of its arguments the same name as an instance variable. When such a case could occur, name the local variable more specifically, because its purpose is more specific. This, too, is a style issue.

当它是访问器时,我将局部变量命名为newX,并将实例变量命名为与属性x相同.这是我自己的个人风格;就像我说的那样,将属性x,ivar mX和局部变量x命名也很好(除了此示例过于简洁之外).

When it is the accessor, I name the local variable newX, having named the instance variable the same as the property, x. This is my own personal style; as I said, naming the property x, the ivar mX, and the local variable x is fine too (aside from the excessive brevity of this example).

这篇关于类属性mVar和实例变量self.mVar之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆