1

我更喜欢像这样在 Objective-C 中使用类的属性(这在较新的 Xcode 版本中似乎是标准的):

/* MyClass.h */
@interface MyClass : NSObject;
@property (nonatomic, strong) NSArray *myArray;
@end;


/* MyClass.m */
#import MyClass.h

@implementation
@synthesize myArray = _myArray;

- (void)anyMethod {
    self.myArray = // do something
}

@end

然而,在网络上的一些 github 存储库中,我发现了使用属性的不同方式,例如:

/* MyClass.h */
@interface MyClass : NSObject {
    NSArray *myArray;
}

// sometimes the @property is used here too

@end;


/* MyClass.m */
#import MyClass.h

@implementation

- (void)anyMethod {
    _myArray = // do something
}

@end

这些方式之间究竟有什么区别?我读到它必须通过访问实例变量来做一些事情。但是为什么有些人在@interface 部分声明变量并且不(或有时)使用@property?

4

3 回答 3

3

这里有几个方面需要考虑,其中一些已经提到过。

首先,下划线只是一个合法字符和名称的一部分。_foo本地 iVar对应于 property或多或少只是一个约定foo。总是这样

  • 你让它们自动合成。(无@synthesize声明)然后自动生成 iVar,并带有前导下划线。(在较新版本的 Objective C 中)
  • 您有意声明 iVar并以它在命名时_foo引用的方式扩展 @synthesize 语句。您也可以声明属性和 ivar并将它们链接到自定义 getter 或自定义 getter 中。这与任何约定相去甚远,因此通常不推荐。例子:_foofoofoobar@synthezise@synthesize foo = _foo;
  • 您提供自定义 getter 和 setter 并访问该属性。同样,您可以将任何 iVar 与该属性链接,甚至可以设置其中的一些以响应输入等。pp。

属性 foo 对应于 ivar foo 时

  • 您使用@synthezise时不提供 ivar 的名称。只是@synthesize foo;(我认为,取决于 ojective-c 的版本,无论是否使用 ivar foo 的 explizit 声明都可以使用,但我不会用血签名)

一般来说,我建议坚持使用下划线模式,尽管我自己并不总是这样做。优点是 ivar 和属性之间的分离对程序员来说更明显,这有助于避免错误。特别是同名的本地参数(很常见)不会隐藏 ivar。示例foo

foo = @1; //This refers to the iVar foo. 
self.foo = @1; //This calls the setter. 
[self setFoo:@1]; //This calls the setter. 
someVar = [self foo]; // This calls the getter. 
foo = foo; // This would not work assuming that foo is a local parameter of the method.
self->foo = foo // This is not good style but a workaround for the line above in that situation. This accesses the ivar directly on the left side of the equation, not its setter.
self.foo = foo; // This is fine when foo is the local parameter.

_foo 也一样,对程序员来说更清楚:

_foo = @1; //This refers to the iVar _foo.  
self.foo = @1; //This calls the setter. 
[self setFoo:@1]; //This calls the setter. 
someVar = [self foo]; // This calls the getter. 
_foo = foo; // This would work nicely assuming that foo is a local parameter of the method.
self->_foo = foo // No need for doing that. It is rather C style anyway and not that common in Obj-C.
self.foo = foo; // This, too, is fine when foo is the local parameter. Clearly uses the setter.
于 2013-05-24T08:56:04.840 回答
0

“_varName”指的是存储在内存中的实际变量。通过使用“self.varName ...”,您只需使用访问器使用点语法约定“获取”和“设置”变量。所以通过这样做

self.varName = someValue;

或者

[self setVarName:someValue];

实际上你正在调用一个方法

- (void)setVarName:(ObjectType *)varName

这只是一个经典的“setter”方法,负责设置该变量的值。这就像走进一家餐馆并与服务员/女服务员一起点菜,而不是走进厨房并自己动手。

通常后者是不受欢迎的,建议您使用访问器方法来设置和获取使用“self ...”的值。这是因为访问器方法通常会设置为“验证”是否存储了适当的数据。在获取或设置值时完成其他任务的自定义访问器更是如此。还有其他原因,但“保护”确实是重点。

当你这样做时

_varName = someValue; 

不使用setter方法,直接改变量。

于 2013-10-04T23:40:54.500 回答
-1
{
 NSArray *myArray;
}

上面的东西被称为成员变量,它不能在类外访问。(重要点)(除非你提供自定义的getter和setter)

如果你创建了一个@property,那么变量可以在类内部和类外部读取..所以为你生成了setter和getter..自动

然后不需要将其声明为成员变量..

这样做是为了提高可读性,它也被认为是内存管理策略的重要组成部分。

当你谈论私有财产时

A. 如果你想要一个完全私有的变量。不要给它财产。

B. 如果您想要一个可从类的封装外部访问的只读变量,请使用全局变量和属性的组合:

于 2013-05-24T08:08:34.320 回答