将子视图添加到视图时,我是@synthesize它,还是在loadView方法中创建它

时间:2013-09-06 02:43:57

标签: iphone ios objective-c

以编程方式将子视图添加到视图的正确方法是什么

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

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,因为您声明了一个与合成变量同名的局部变量。