Ios 以编程方式创建视图强属性

Ios 以编程方式创建视图强属性,ios,objective-c,properties,Ios,Objective C,Properties,之前,我一直在使用interface builder创建视图 当用故事板或笔尖创建视图时,我会连接插座。据我所知,这些门店正在与景观上的房产建立紧密的联系 如果我以编程方式创建视图,我的属性是否应该是强的 h 有几件事: 您的代码没有使用您定义的属性 不要将私有属性放在.h文件中 不要声明您的类符合.h文件中的UITextFieldDelegate协议 至于属性应该是strong还是弱我更喜欢strong,但由于您将要将这些属性(视图)添加到视图控制器的视图中,因此最好将它们设置为弱,因为只要视

之前,我一直在使用interface builder创建视图

当用故事板或笔尖创建视图时,我会连接插座。据我所知,这些门店正在与景观上的房产建立紧密的联系

如果我以编程方式创建视图,我的属性是否应该是强的

h

有几件事:

  • 您的代码没有使用您定义的属性
  • 不要将私有属性放在.h文件中
  • 不要声明您的类符合.h文件中的
    UITextFieldDelegate
    协议
  • 至于属性应该是
    strong
    还是
    我更喜欢
    strong
    ,但由于您将要将这些属性(视图)添加到视图控制器的视图中,因此最好将它们设置为
    ,因为只要视图控制器处于活动状态,就会始终存在对它们的引用

    您的.h应该是:

    @interface LoginViewController : UIViewController
    @end
    
    您的.m应该是(假设您确实希望使用这些属性):

    @interface LoginViewController()
    @属性(非原子,强)UIView*loginView;
    @属性(非原子,强)UITextField*usernameTextField;
    @属性(非原子,强)UITextField*passwordTextField;
    @属性(非原子,强)UIButton*signInButton;
    @结束
    @实现LoginViewController
    -(无效)初始视图和布局
    {
    self.loginView=[[UIView alloc]init];
    self.loginView.frame=self.view.bounds;
    [self.view addSubview:self.loginView];
    //...
    }
    @结束
    
    当您使用strong属性时,您基本上是在编写
    retain
    ,如中所示,您希望Objective-C为属性分配内存并将其保持到释放为止

    这都是强有力的手段

    这仅在使用ARC时才有必要(尽管您仍然可以在ARC中使用retain)。如果没有,请使用retain

    “如果我以编程方式创建视图,我的属性是否应该是强属性?”


    如果它们是对象而不是基本体,则是。

    如果您希望手动创建属性,而不使用xib或故事板,我建议您使用强属性创建属性

    作为
    initViewsAndLayout
    中的代码,如果始终在同一方法范围内创建子视图并同时将其添加到viewcontroller的视图中,则即使使用“弱”或“指定属性”,也没有问题<代码>添加子视图将增加子视图的引用计数。但是,我认为这不是一个好习惯,因为我们所有人都可能犯错误


    因此,最好使用强属性创建UIView属性。

    作为简单的经验法则

  • 任何视图始终由其所有者拥有(通过强引用维护) superview,当它们添加到superview时
  • 顶层视图始终由其VC拥有(通过强引用维护)
  • 现在,可以通过两种不同的方式将视图添加到superview中

    • 从代码创建视图并使用
      addSubview:
      方法将其添加到某个超级视图时。(这就是你的问题所暗示的)
    • 从nib文件加载视图层次结构时。(这里还有隐式的
      addSubview:
      调用由UIKit创建层次结构),因此子视图通过强引用其各自的超级视图来保留
    因此,在这两种情况下,视图都被它们的超级视图隐式保留,因此在顶级视图自行处理之前,永远不会被处理。因此,为子视图声明
    strong
    属性会对子视图施加另一种所有权:

    • 其superview的隐含所有权,以及
    • 财产的明确所有权
    因此,一般来说,不需要为子视图声明
    strong
    属性,但是它是(从nib/按代码)创建的

    但是,在某些特殊情况下,可能需要为视图声明
    strong
    属性。例如,当一个视图应被删除并重新添加到其superview中时,该视图应声明为强视图。从其superview中删除此类视图时,superview也会释放其所有权。因此,如果我们需要维护该视图的强引用,如果我们需要再次将同一视图分配给某个超级视图。在这种情况下,对视图的
    strong
    属性引用变得很方便,并且不允许发布视图


    附言:

    当使用故事板或笔尖创建视图时,我会连接 经销店。我知道这些门店正在创造一个强大的市场 连接到视图上的属性

    我发现在你的问题中,仅仅有一个误解。从故事板/nib创建视图时,outlets不会创建任何所谓的
    strong
    属性连接
    IBOutlet
    s仅描述属性如何加载视图。对于outlet属性,该属性所指向的视图是未归档的,如果尚未加载该视图,则该视图将被加载。但是,它的保留仍然取决于
    strong
    /
    属性访问器。

    您询问:

    如果我以编程方式创建视图,我的属性是否应该是
    strong

    答案分两部分:

  • 视图控制器应保持对其顶层视图的
    strong
    引用

    当根本不使用NIB或故事板并且以编程方式执行所有操作时,根视图将在
    loadView
    中实例化,并且通常存储在
    retain
    /
    strong
    属性中
    UIViewController
    已经有一个
    view
    属性,该属性带有
    retain
    内存语义,这是常用的。(有关以编程方式创建的视图的详细信息,请参阅《iOS视图控制器编程指南》的“视图控制器中的资源管理”一章中的部分)

    (如果您不是在
    loadView
    中创建根视图,而是在实例化
    @interface LoginViewController ()
    
    @end
    
    @implementation LoginViewController
    
    - (void)initViewsAndLayout
    {
       _loginView = [[UIView alloc] init];
       _loginView.frame = self.view.bounds;
       [self.view addSubview:_loginView];
    
       //...
    }
    @end
    
    @interface LoginViewController : UIViewController
    @end
    
    @interface LoginViewController () <UITextFieldDelegate>
    
    @property (nonatomic, strong) UIView *loginView;
    @property (nonatomic, strong) UITextField *usernameTextField;
    @property (nonatomic, strong) UITextField *passwordTextField;
    @property (nonatomic, strong) UIButton *signInButton;
    
    @end
    
    @implementation LoginViewController
    
    - (void)initViewsAndLayout
    {
       self.loginView = [[UIView alloc] init];
       self.loginView.frame = self.view.bounds;
       [self.view addSubview:self.loginView];
    
       //...
    }
    
    @end