我是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是一种快捷方式,可以避免无聊的吸气剂和制定者。
但我有一些问题:
是否必须合成IBOutlets?
答案 0 :(得分:7)
来自Memory Management of Nib Objects,
当加载nib文件并建立出口时,nib加载机制总是使用存取方法(如果它们存在)(在Mac OS X和iOS上)。因此,无论您开发哪个平台,通常都应使用Objective-C声明的属性功能声明出口。
对于iOS,您应该使用:
@property(nonatomic,retain)IBOutlet UIUserInterfaceElementClass * anOutlet;
然后你应该合成相应的访问器方法,或者根据声明实现它们,并且(在iOS中)在dealloc中释放相应的变量。
答案 1 :(得分:3)
在实现的代码中,tableView永远不会被显式调用,但是dealloc会释放它;
这是因为当你做为tableView分配一个值时,你的控制器会保留它,并且当它被dealloc'd时它需要释放它。不要忘记,在界面中声明的@properties是公共可访问的。在具体情况下,您使用您在文件所有者和UITableView之间的Interface Builder中定义的连接,通过视图控制器loadView
方法初始化您声明为IBOutlet的tableView。
如果永远不会明确调用为什么@synthesize?
您需要为所有声明的@properties提供访问器。它们可以是@synthesized,也可以自己编写。
是否必须合成IBOutlets?
不,但这样方式更方便。编译器强制执行的规则是@properties 必须在实现中具有相应的访问者(合成与否)。
答案 2 :(得分:2)
供参考:不再需要来自Xcode 4.4和LLVM Compiler 4.0的@synthesize指令,因为默认情况下会为接口中定义的@properties提供它。
答案 3 :(得分:1)
如果您输入
@property (nonatomic, retain) IBOutlet UITableView *tableView;
你告诉编译器:“听着,会有一个吸气剂和一个定位器。如果合适的话,使用它们!”它会在加载笔尖时使用它们。
因此,您必须实现getter和setter,否则编译器会抱怨。
答案 4 :(得分:0)
IBoutlet伪类型只是一个标记,因此InterfaceBuilder“知道”所提到的类文件具有UITableView实例的句柄/出口。
预处理器正在删除编译IBOutlet时(InterfaceBuilder解析(查看)源文件)。它与IBAction类似:它被预处理器替换为void。
那就是说,你可以使用对所述实例的引用以编程方式执行操作(比如添加/更改UITableView的值)