0

我正在观看一个演示,我意识到我不了解关于目标 c 编程风格的一些基本知识。该演示恰好是斯坦福 CS193P 的第 14 课。请参阅下面的代码,看看是什么让我感到困惑。我认为与二传手有关。

@synthesize photoDatabase = _photoDatabase;

- (void)setPhotoDatabase:(UIManagedDocument *)photoDatabase
{
    if (_photoDatabase != photoDatabase)
        _photoDatabase = photoDatabase;
}

此代码来自本讲座/演示的 youtube 视频中的 25:00 。此处称为 photoDatabase 的合成属性恰好是 UIManagedDocument 类型。

我的第一个问题是,为什么我们要在@synthesize myProperty = _myProperty 中使用下划线。我对此有点困惑,一般来说都是编程新手。从 XCode 4 开始,我们在引用此属性时是否部分地合成以消除对下划线的需要?

我的第二个问题是 setPhotoDatabase: 方法的目的是什么。我假设讲师正在覆盖这种方法。究竟是为了什么目的?

4

3 回答 3

5

我将解决您的第一个问题...当您使用综合属性时,您只是为实例变量自动创建 setter 和 getter。假设你有:

@property (nonatomic, strong) NSString *title;

合成:

@synthesize title;

创建以下方法:

- (NSString) title;
- (void) setTitle:(NSString *)value;

现在在您的班级中,您想要访问 title 属性,您可以使用titleor来实现self.title。尽管这两者看起来是同一件事,但它们并非如此。title访问实例变量本身,同时self.title访问“综合”方法- (NSString) title;

如果我们有某种方法可以更容易地区分这两者,难道不是让事情变得更简单吗?嗯,这正是它@synthesize title = _title;的用武之地。它创建了标准的 setter 和 getter,但将实例变量设置为_title而不是title.

编辑:较新版本的 Xcode(我相信 4.3 及更高版本)会自动@synthesize <variable> = _<variable>为您包含 ,因此您无需自己执行此操作。

于 2013-06-28T09:30:55.013 回答
2

下划线是生成实际 ivar 的默认方式。它可以让你成为一种元。在您的类内部,您可以像这样直接引用它们,避免对 getter 或 setter 进行不必要的方法调用。它还保持范围清晰,并允许您在其他方法声明中使用与属性和 getter 相同的名称作为参数的变量名称。这隐含了该方法的参数旨在与该属性相关。下划线可防止局部变量与方法内的 ivar 发生冲突。

您可以通过手动将 ivar 名称合成为非常不同的东西来故意掩盖子类创建者的 ivar 名称。
使用它是为了保护 ivar 免受子类创建者的影响,以防万一你的 SPI 无法使用它。

像这样的 setter 方法的目的是符合约定和键值编码。其他类使用它来设置 ivar。

当您需要提供一些超出为您综合的功能时,您可以手动实现自己的 setter。这可能包括数据验证或触发通知或其他事情。

于 2013-06-28T09:48:36.737 回答
1

下划线只是将变量标记为实例变量的一种方式,而不是方法变量。使用公共成员是一种不好的做法,因此使用 setter 和 getter 是正常的。@synthesize根据关键字后的@property关键字自动生成 getter 和 setter。它可以生成retainstrong使用arc时)、assignweak使用arc时)等setter和getter。

您也可以覆盖任何这些自动生成的方法来添加一些逻辑。例如,您可能希望每次更改此值时都将消息打印到控制台,或者在更改属性后更新视图。

于 2013-06-28T09:36:57.513 回答