简体   繁体   中英

When adding subviews to a view, do I @synthesize it, or create it inside loadView method

What is the correct way of programmatically adding subviews to a view,

A) using @property:

// SampleViewController.h
@interface SampleViewController : UIViewController

@property (nonatomic, weak) UITableView *subTableView;
@end

// SampleViewController.m
@synthesize subTableView = _subTableView;

or B) in loadView:

// SampleViewController.m 
- (void)loadView
{
    UITableView *subTableView = [[UITableView alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:subTableView];
}

Again, this is assuming I am not using IB at all. What is the difference between the two (because in practice both seems to work)?

Additional question, if I have both the A) and B) codes in SampleViewController.m , why does XCode allow me to use subTableView as variable name in B, even though I already used that name in the @synthesize part of the code?

Update: I did a bit of digging around and turns out the @synthesize keyword is no longer needed starting from XCode 4.4 .

Depends on your needs. If you wish to add it once and forget about it, a local variable is enough. It will be retained by the superview, and will not be released.

However, if you wish to access it later, you could use an instance variable or a property to keep a reference to your view.

Whether your property is weak or strong depends on your usage, again. If you add it to a superview and don't remove it again, weak is enough because it is retained by the superview. If, however, you dynamically add it and remove it, for example show it in landscape but remove it in portrait, then you would want the property to have a "strong" modifier, so that the object is retained even when not part of the view hierarchy.

如果要访问两个不同类中的对象,则使用@property,这是更好的方法,因为我们也可以释放它,否则,如果要在本地使用它,则使用局部变量就足够了

First method is fine. But for second one, it's not correct. You need do like this

// 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];
}

or you can add subviews in -viewDidLoad: method:

- (void)viewDidLoad
{
  [super viewDidLoad];

  UITableView *subTableView = [[UITableView alloc] initWithFrame:self.view.bounds];
  [self.view addSubview:subTableView];
  // If not use ARC, ...: [subTableView release];
}

If you need to update view data frequently after the view did load, you'd better declare subviews like the first way you mentioned.

As you state, either (A) or (B) works. If you need to reference subTableView in other methods besides loadView, then you should use (A).

As to the additional question, you can use subTableView in (B) because you're declaring a local variable with the same name as the synthesized variable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM