9

很多人都问过这个问题,但是这个问题是为了获得有关何时使用这些方法的示例。请使用 setter 和 getter 无限循环以外的示例

例子。

.h -
@property(nonatomic, strong)NSMutableArray* mutArray
.m -
@synthesize mutArray= _mutArray;

1)我想要:
_mutArray = [[NSMutableArray alloc] init];
或者
self.mutArray=[[NSMutableArray alloc] init];
我为什么要做每一个,有什么区别?!

2)如果我想向它添加一个对象......
[_mutArray addObject:object];
或者
[self.mutArray addobject:object];

为什么?

非常感谢!

4

3 回答 3

13

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 之后,始终如一地使用访问器也是很好的防御性编程,我强烈推荐它。

于 2013-03-26T18:35:54.233 回答
0

_mutArray 是 iVar,self.mutArray 通过 @synthesize 属性时为您创建的 getter 和 setter 访问属性。您可以根据自定义内容覆盖这些 getter 和 setter。在您的示例中,您的属性设置为强,这会为您的属性添加保留。所以 self.mutarray = [[NSMutableArray alloc] init]; 会做这样的事情(除非你覆盖属性的设置器):

-(void)setMutarray:(NSMutableArray*)_mutArray{
    if(_mutArray != mutArray){
        [mutArray release];
        mutArray = nil;
        mutArray = [_mutArray retain];
    }
}

要将对象添加到数组中,您只需要访问 iVar,而不是属性,除非您在 getter 中进行自定义操作。例如,您的吸气剂可能如下所示:

-(NSMutableArray*)mutArray{
    if(!mutArray){
        self.mutArray = [[[NSMutableArray alloc] init] autorelease];
    }
    return mutArray;
}

通过这种方式,您可以确保始终有一个真实的数组来添加对象。如果是这种情况,您会想要使用 [self.mutArray addObject:object];

因此,除非您想在 getter 或 setter 中进行自定义操作,否则您只想访问 iVar。

于 2013-03-26T18:24:24.797 回答
0

selfkeyword就像this keywordJAVA. _

它访问当前对象,也是一个指向对象的指针。

有关self阅读本教程的更多信息

_ObjeNameiVar被调用Objective c

在实现中声明的实例变量是隐式隐藏的(实际上是私有的),并且可见性不能改变- @public, @protected and @private不会产生编译器错误(至少是当前的 Clang)但被忽略。

例如 :

之间的不同

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

以上示例我从这个问题中得到。

于 2013-03-26T18:42:46.407 回答