创建视图编程强Vs的控制器中弱子视图

pro*_*ist 1 weak-references objective-c ios

我正在使用Xcode 5.1.1为iOS 7.1编写一个小测试程序.我不使用XIB或故事板.一切都是以编程方式完成的.在AppDelegate.m中,我创建了一个TestViewController的实例,并将其设置为窗口的rootViewController.在TestViewController.m中,我覆盖"loadView"来创建和分配控制器的主视图.

TestViewController.h
--------------------
  @interface TestViewController : UIViewController
  @property (nonatomic, weak) UILabel *cityLabel ;
  @end

TestViewController.m
--------------------
  @implementation TestViewController

  - (void)loadView
  {
      UIView *mainView = [[UIView alloc] init]  ;
      self.view = mainView ;
  }

  - (void) viewDidLoad
  {
      UIView *addressView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)] ;
      [self.view addSubview:addressView] ;

      [self createCityLabel:addressView] ;
  }

  - (void) createCityLabel:(UIView *)addressView
  {
      // Warning for below line - Assigning retained object to weak property...
      self.cityLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 80, 30)] ;

      [addressView addSubview:self.cityLabel] ;
  }

  @end
Run Code Online (Sandbox Code Playgroud)

根据我的理解,所有权如下

testViewController ---(强) - > self.view - (强) - > addressView的对象 - (强) - > self.cityLabel的对象.

因此,self.cityLabel可以是对其目标Object的弱引用

self.cityLabel - (弱) - > self.cityLabel的对象.

我也通过一些其他的问题,在这里类似的问题.建议将ViewOtroller中的IBOutlet属性保持为"弱"(尽管不是强制性的,除非有循环引用).只有维持强参考是到控制器的主视图.

但是,我在createCityLabel函数中收到警告,如图所示.这消失,如果我删除"弱"属性.这真令人困惑.是保持弱只适用于那些使用XIB /故事板创建奥特莱斯的建议?

Nei*_*eil 8

你的cityLabel属性可以是弱,但你必须把它添加到视图层次结构,然后才能分配财产或将其分配给一个标准的(强引用)变量.

发生了什么事情,你正在创建一个UILabel,然后将其分配给一个不承担它的所有权(弱)的财产.在你走过这self.cityLabel = [[UILabel alloc] ...条线后,UILabel已经被解除分配并且cityLabel属性为零.

这将正确地做你想要的:

UILabel *theLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 80.0f, 30.0f)];
self.cityLabel = theLabel;
[addressView addSubview:theLabel];
Run Code Online (Sandbox Code Playgroud)

变量theLabel将保留UILabel期间的范围createCityLabel:并添加UILabel作为一个子视图的视图是视图控制器的视图将保留它的视图控制器的寿命(除非你删除的部分UILabel从视图或任何一种UILabel的父视图)).

  • 是的,对于.xib,视图会立即保留视图.您可以完成[addressView addSubview:[[UILabel alloc] init]],它会将其添加到视图中并保留,但很明显,访问您刚刚创建的对象变得很尴尬(您必须经历视图子视图并找到它). (2认同)
  • 我怀疑做[addressView addSubview:(self.cityLabel = [[UILabel alloc] init])]; 应该按预期工作.只要对象被"分配"给对象,对象就应该保持分配状态. (2认同)