@synthesize IBOutlet property



我是一个Objective-C新手,我正在阅读Alasdair Allan的《iPhone编程》。在阅读时,我发现了以下代码:

@interface RootController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
    UITableView *tableView;
    NSMutableArray *cities;
}
// warning: remember this tableView
@property (nonatomic, retain) IBOutlet UITableView *tableView;

相对实现是这样开始的:

@implementation RootController
@synthesize tableView;

现在:我知道@synthesize是一种避免无聊的getter和setter的捷径。

但是我有一些问题:

    tableView 从来没有显式调用过,但是dealloc会释放它;
  1. 如果它从未被显式调用,为什么要@synthesize?

IBOutlets是否必须被合成?

From Memory Management of Nib Objects,

当一个nib文件被加载并建立出口时,nib加载机制总是使用访问方法(如果它们存在的话)(在Mac OS X和iOS上)。因此,无论你为哪个平台开发,你都应该使用Objective-C声明的属性特性来声明出口。

对于iOS,你应该使用:

@property (nonatomic, retain) IBOutlet UIUserInterfaceElementClass *anOutlet;

然后你应该合成相应的访问方法,或者根据声明实现它们,并(在iOS中)在dealloc中释放相应的变量。

tableView从来没有被显式调用过,但是dealloc会释放它;

那是因为当你给tableView赋值时,你的控制器会保留它,当它被dealloc时它需要释放它。不要忘记,在接口中声明的@properties是可公开访问的。在你的例子中,你声明为IBOutlet的tableView是由视图控制器loadView方法初始化的,使用你在Interface Builder中定义的文件所有者和UITableView之间的连接。

如果它从未被显式调用,为什么要使用@synthesize?

您需要为所有声明的@properties提供访问器。它们可以是@合成的,或者您可以自己编写。

IBOutlets是否必须被合成?

不,但是那样更方便。编译器强制执行的规则是@properties 必须在实现中有相应的访问器(合成的或非合成的)。

参考:从Xcode 4.4和LLVM编译器4.0中,@synthesize指令不再需要,因为它将默认为接口中定义的@properties提供。

如果你输入

@property (nonatomic, retain) IBOutlet UITableView *tableView;

你告诉编译器:"听着,这里会有getter和setter。如果合适的话,使用它们!"它会在加载nib时使用它们

因此你必须实现getter和setter,否则编译器会报错。

IBoutlet伪类型只是一个标记,这样InterfaceBuilder"知道"提到的类文件有一个UITableView实例的句柄/出口。

编译时IBOutlet被预处理器删除(InterfaceBuilder解析(查看)源文件)。这与IBAction类似:它被预处理器替换为void。

也就是说,你可以使用所述实例的引用以编程方式做一些事情(如添加/更改UITableView的值)

相关内容

最新更新