gpt4 book ai didi

iphone - 类属性 mVar 和实例变量 self.mVar 的区别

转载 作者:太空狗 更新时间:2023-10-30 03:58:38 41 4
gpt4 key购买 nike

对于通过 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;
}

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

self.mName = name;

对比

mName = name;

这不是@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];
}

但是假设我访问 countLabel 为:

self.countLabel

有什么区别?

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

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

//In .m file:
@synthesize mVar;

mVar = @"";

对比

 self.mVar = @"";

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

谢谢大家!

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

所以您认为 mVarName 的约定不好?这是我在 C++ 时代学到的。

但是当你这样做的时候呢?

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

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

但是你可以这样做:

-(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)。也就是说,该语句隐式转换为此消息表达式语句:

[self setMName:name];

(像这样笨拙的访问器名称就是为什么“mName”是一个糟糕的属性名称。有属性声明语法可以解决这个问题,让你命名属性“name”和你的实例变量“mName”并映射一个给另一个。)

第二个示例直接访问实例变量——没有访问器消息。

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

Say it is this though, …

如果没有为类声明名为“mName”的属性,则您不能使用属性访问语法来访问该类实例上具有该名称的属性。

无论您是综合访问器、使用@dynamic 将它们传递给父类(super class),还是您自己定义它们,都无关紧要。这就是对象将如何响应访问器消息,但编译器生成的访问器消息不会有什么不同(因为属性访问可以很容易地来自类外部和类内部)。

Say it the iVar wasn't an 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 也很好(除了过于简洁之外示例)。

关于iphone - 类属性 mVar 和实例变量 self.mVar 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2278389/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com