IBOutlet 创建的不同方法

Different methods for IBOutlet creation

在Objective-C中至少有3种创建IBOutlet的方法,用于制作iOS 10 App,在Xcode 8.

方法一:在ViewController.h

@interface ViewController : UIViewController
@property (nonatomic, strong) UILabel *textLabel;
@end

方法二:在ViewController.m

界面中
@interface ViewController () {
    IBOutlet UILabel *textLabel;
}

@end

方法三:在ViewController.m的界面中,使用@property

@interface ViewController () 
@property (nonatomic, strong) UILabel *textLabel;
@end

考虑到 textLabel 必须访问并且需要经常更新其文本,哪种方法是正确的方法?

这完全取决于您是否需要 class 插座之外的插座可以访问您的插座;通常我不鼓励这样做,因为让您的视图控制器负责更新您的 UI 而不是将此任务传递给其他 classes 是一种很好的做法。话虽如此,方法 3 将是最佳选择,但是,如果您确实必须从另一个 class 访问您的 object,那么只需使用 方法1 所以它暴露在你的class header.

方法 2 使用 iVars 而不是 object 属性,不是声明出口的正确方法,它甚至可能导致意外行为,因此最好避免这种情况方法。

您的代码没有正确的 IBOutlet。 Outlets 是与 Storyboard 的连接。

方法一

这是一个属性。因为它在 .h 文件中,所以可以从外部访问它。 public.

的 Objective-C 模式

方法二

这是 iVar。如果没有必要,请不要使用 iVars。

方法三

这是一个属性。由于它在 .m 文件中,因此无法从外部访问它。 private.

的 Objective-C 模式

方法四

一个合适的 IBOutlet 看起来像这样:

@interface ViewController ()
    @property (nonatomic, weak) IBOutlet UILabel *label;
@end

很简单属性。您必须根据是否要发布它来决定是将它放在 .h 还是 .m 文件中。

IBOutlet 只是让 属性 可以连接到 Storyboard。这是 Xcode 的注解,不会改变代码的语义。


编辑 1:

正如 Sulthan 在评论中正确提到的那样:

In most situations the correct design pattern is to hide outlets because it's an implementation detail. External classes should not set data directly using views.


编辑 2:

为什么 "not to use iVars if you do not have to" (2)

基于意见:

我认为使用 getter 和 setter(因此不直接访问变量)是良好的 OOP 实践。正如您在阅读 x = self.variable(属性)和 x = variable(局部变量)时所知道的那样,代码也更容易阅读。

如果您出于某种原因必须使用 iVars,通常(我建议)在名称前加上 _x = _variable (iVar).