Objective-C 属性 Getter/Setter 崩溃 EXC_BAD_ACCESS

Objective-C Property Getter/Setter crash EXC_BAD_ACCESS

我想知道为什么给另一个 class 中的属性赋值会导致 EXC_BAD_ACCESS。我似乎无法弄清楚为什么。

1.) 发送到 setter 的值不是零; 2.) 尝试赋值时,EXC_BAD_ACCESS 发生,变量为 nil;

在 Cocoa 和 Cocoa Touch 应用程序中使用此模式都会导致 EXC_BAD_ACCESS,所以我不认为这是平台问题,但我相信这是我的模式使用。

我的问题是,是在分配变量时,还是我创建属性的方式?

我创建了一个虚拟项目,如下图所示。

感谢任何帮助。

编辑:进行一些挖掘,我将 setter 的变量名称(不是 属性 名称)更改为 firstName__。基本上,setter 中的代码用于 setFirstName:

- (void)setFirstName:(NSString *)firstName__
{
    self.firstName = firstName__;
}

通过说 firstName__(而不是 self.firstName)等于 nil,即使在 AppDelegate 中,该值不为 nil,这样做也消除了一些混乱。

你的问题是递归。在 setter 中,您一次又一次地调用 setter 方法。 当你声明

self.firstName = first name__;

基本上等同于

[self setFirstName:first name__];

所以该方法正在调用自身,这没有多大意义。

您首先需要了解属性和实例变量。

Objective C class 实例通常包含保存值的实例变量。 尽管可以通过 @public 限定符将这些变量暴露给外界,但这不是既定的约定。 约定是要有属性,在幕后是 "wrapper" 围绕 私有实例变量 。 由于在 Objective C 中您只能通过消息与其他对象通信,因此为了能够访问实例变量的值,您可以在发送适当的消息时调用 setter 和 getter 方法到对象。

现代 objective C 在您声明属性时隐式地为您创建实例变量。人们常说这些属性由实例变量支持。

通常没有理由显式实现 setters 和 getters,因为编译器会在幕后为您完成。 (以同样的方式,它也为你创建了那些实例变量)

但是如果要显式实现setters,需要在setter中设置实例变量,而不是调用[=54] =] 本身(通过点符号约定),正如我上面解释的那样。

隐式创建的实例变量具有以下划线作为前缀的命名约定。在你的情况下是

_firstName

当你声明一个名为 firstName 的 属性 时,你也会得到一个实例变量
_名字

你setter应该是这样的

-(void)setFirstName:(NSString *)firstName 
{ 
    _firstName = firstName;
} 

和getter

-(NSstring *)getFirstName
{
    return _firstName;
}