这已被问了很多,但这个问题是要举例说明何时使用这些方法。请使用setter和getter无限循环以外的示例
例子。
.h -
@property(nonatomic, strong)NSMutableArray* mutArray
.m -
@synthesize mutArray= _mutArray;
1)我想要:
_mutArray = [[NSMutableArray alloc] init];
OR
self.mutArray=[[NSMutableArray alloc] init];
为什么我会做他们每个人,有什么区别?!
2)如果我想添加一个对象...
[_mutArray addObject:object];
OR
[self.mutArray addobject:object];
为什么?!
非常感谢!
答案 0 :(得分:12)
您应该只在init
和dealloc
中处理您的ivars,或者在实现细节绝对需要的地方(例如访问者本身内部,或实际需要内存地址的地方)。除了在这些地方,您应该始终使用访问者,这意味着[self foo]
而不是_foo
。
self.foo
只是实际调用的语法糖,即[self foo]
。重要的是要理解self.foo
是标准的ObjC消息发送,并且与[self foo]
完全相同。按照惯例,您只应在引用属性时使用点语法。
预ARC,根据我的经验,直接使用ivars是导致崩溃的首要原因。在没有ARC的情况下直接分配到ivar时,你搞砸的可能性很快超过了程序范围的100%。
自ARC以来,我仍然认为你应该总是使用访问器(除了上面给出的例外),但原因更为微妙。它的主要原因是可以在当前类,子类中或通过KVO(完全在代码之外发生)自定义访问器。如果您直接访问ivar,那么您将绕过它。例如,假设该属性是懒惰创建的(这很常见)。然后,如果您在创建之前使用ivar,您将获得微妙的错误。因此,您必须记住,对于该属性,始终使用访问者。同样,您可以致电setNeedsDisplay
或发布通知等。
如果你有一个简单的规则,说“我将永远使用访问者”,那么很容易看到代码并知道它是正确的。在少数情况下你需要规避访问者,_
说“嘿,请注意这里,我做的事情很奇怪。”
如果您有一个规则“我将使用访问器来处理需要它的属性,而不是那些不需要它的属性”,那么几乎不可能查看代码并知道它是否正确。以前的开发人员是否使用了ivar,因为它是必需的,或者只是因为他觉得这样?你能改变它吗?这很难知道。
所以即使是在ARC之后,使用访问器仍然是很好的防御性编程,我强烈推荐它。
答案 1 :(得分:0)
_mutArray是iVar,self.mutArray通过@synthesize属性为您创建的getter和setter访问属性。您可以将这些getter和setter覆盖到适当的自定义内容。在您的示例中,您将属性设置为strong,这会为您的属性添加一个保留。所以self.mutarray = [[NSMutableArray alloc] init];会做这样的事情(除非你覆盖了属性的setter):
-(void)setMutarray:(NSMutableArray*)_mutArray{
if(_mutArray != mutArray){
[mutArray release];
mutArray = nil;
mutArray = [_mutArray retain];
}
}
要将对象添加到数组中,您只想访问iVar,而不是属性,除非您在getter中执行自定义操作。例如,你的getter可能是这样的:
-(NSMutableArray*)mutArray{
if(!mutArray){
self.mutArray = [[[NSMutableArray alloc] init] autorelease];
}
return mutArray;
}
通过这种方式,您可以确保始终有一个真正的数组来添加对象。如果是这种情况,您可能希望使用[self.mutArray addObject:object];
所以,除非你想在getter或setter中做一些自定义的事情,否则你只想访问iVar。
答案 2 :(得分:0)
self
keyword
与this
中的keyword
JAVA
类似。
它访问当前对象,它也是指向对象的指针。
for more info about self
read this tutorial
_ObjeName
在iVar
Objective c
实现中声明的实例变量被隐式隐藏(有效私有)并且无法更改可见性- @public, @protected and @private
不会产生编译器错误(当前Clang至少< / em>)但被忽略了。
例如:
之间的差异
1) NSString *someString = _name;
2) NSString * someString = self.name;
假设你的.m文件中有这一行(并且没有任何覆盖方法来直接访问_name)
@synthesize name = _name;
这意味着当您尝试访问它时,属性name
(self.name)将使用变量_name。在这种情况下,self.name
等于_name
但是如果你有名字的动态属性,就像这样:
-(NSString)name{
return @"1234";
}
然后有区别。 self.name
将始终返回1234,但_name可能不等于此值。
示例:
_name = @"555";
NSLog(_name);
NSLog(self.name);
结果:
2012-02-09 14:27:49.931 ExampleApp[803:207] 555
2012-02-09 14:27:49.933 ExampleApp[803:207] 1234