【问题标题】:Objective-C Property Getter/Setter crash EXC_BAD_ACCESSObjective-C 属性 Getter/Setter 崩溃 EXC_BAD_ACCESS
【发布时间】:2015-02-20 20:42:10
【问题描述】:

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

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

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

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

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

感谢任何帮助。

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

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

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

【问题讨论】:

  • 忘了说,我可以通过在 AppDelegate 中使用相同的设置器并在 PersonInfo.m 中删除它们并添加 @synthesize firstName, lastName; 来获得所需的结果;打电话。
  • AFAIK,您不再需要创建 setter/gettings 或合成它们。只需将属性添加到标题中,就可以了。如果您想在设置变量时执行其他操作,则需要覆盖设置器。

标签: objective-c cocoa properties crash null


【解决方案1】:

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

self.firstName = first name__;

基本上相当于

[self setFirstName:first name__];

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

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

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

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

通常没有理由显式实现 setter 和 getter,因为编译器会在幕后为您执行此操作。 (以同样的方式,它也会为你创建那些实例变量)

但如果你想显式地实现 setter,你需要在 setter 中设置实例变量,而不是像我上面解释的那样再次调用 setter 本身(通过点符号约定)。

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

_firstName

当您声明一个名为 firstName 的属性时,您还会获得一个实例变量
_名字

你的 setter 应该是这样的

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

和吸气剂

-(NSstring *)getFirstName
{
    return _firstName;
}

【讨论】:

  • 我明白你的意思。谢谢你的解释。
  • getter 应该类似于-(NSString *)firstName
猜你喜欢
  • 2013-02-25
  • 1970-01-01
  • 1970-01-01
  • 2014-02-27
  • 2023-03-30
  • 1970-01-01
  • 2023-03-12
  • 2010-11-14
  • 1970-01-01
相关资源
最近更新 更多