以编程方式将子视图添加到视图的正确方法是什么
A)使用@property:
// SampleViewController.h
@interface SampleViewController : UIViewController
@property (nonatomic, weak) UITableView *subTableView;
@end
// SampleViewController.m
@synthesize subTableView = _subTableView;
或B)在loadView中:
// SampleViewController.m
- (void)loadView
{
UITableView *subTableView = [[UITableView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:subTableView];
}
同样,这是假设我根本不使用IB。两者之间有什么区别(因为在实践中两者似乎都有效)?
另外一个问题,如果SampleViewController.m
中同时包含A)和B)代码,为什么XCode允许我在B中使用subTableView
作为变量名,即使我已经在代码的@synthesize
部分?
更新
我做了一些挖掘,结果@synthesize
关键字是no longer needed starting from XCode 4.4。
答案 0 :(得分:2)
取决于您的需求。如果您希望添加一次而忘记它,那么局部变量就足够了。它将由superview保留,不会被释放。
但是,如果您希望稍后访问它,可以使用实例变量或属性来保持对视图的引用。
您的财产是弱还是强,取决于您的使用情况。如果将其添加到超级视图并且不再将其删除,则弱视就足够了,因为它由superview保留。但是,如果您动态添加并删除它,例如以横向显示但以纵向删除它,那么您希望该属性具有“强”修饰符,以便即使不是查看层次结构。
答案 1 :(得分:2)
如果要访问两个不同类中的对象,则使用@property,这是更好的方法,因为我们也可以释放它,如果你想在本地使用它,本地变量就足够了
答案 2 :(得分:1)
第一种方法很好。但对于第二个,这是不正确的。你需要这样做
// SampleViewController.m
- (void)loadView
{
CGRect frame = ...
UIView * view = [[UIView alloc] initWithFrame:frame];
UITableView *subTableView = [[UITableView alloc] initWithFrame:frame];
// Warn: it's |view|, not |self.view|,
// should not use |self.view| in this method except the retain process at bottom,
// i.e.: |self.view = view|.
[view addSubview:subTableView];
// If not use ARC, you need to release the view here: [subTableView release];
// Note: |-loadView| is for |self.view| in case the view does not exist.
// Generally specking, it'll only be dispatched once.
self.view = view;
// If not use ARC, ...: [view release];
}
或者您可以在-viewDidLoad:
方法中添加子视图:
- (void)viewDidLoad
{
[super viewDidLoad];
UITableView *subTableView = [[UITableView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:subTableView];
// If not use ARC, ...: [subTableView release];
}
如果您需要在视图加载后经常更新视图数据,最好像您提到的第一种方式一样声明子视图。
答案 3 :(得分:1)
正如您所述,(A)或(B)都有效。如果你需要在loadView之外的其他方法中引用subTableView,那么你应该使用(A)。
关于附加问题,您可以在(B)中使用subTableView,因为您声明了一个与合成变量同名的局部变量。