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

时间:2014-02-13 02:36:08

标签: ios objective-c properties

以前我一直在使用界面构建器创建我的视图。

使用故事板或笔尖创建视图时,我会连接我的网点。据我所知,这些网点正在与视图中的属性建立强大的联系。

如果我以编程方式创建视图,我的属性应该很强吗?

·H

@interface LoginViewController : UIViewController <UITextFieldDelegate>

@property (nonatomic, strong) UIView *loginView;

@property (nonatomic, strong) UITextField *usernameTextField;
@property (nonatomic, strong) UITextField *passwordTextField;

@property (nonatomic, strong) UIButton *signInButton;

@end

的.m

@interface LoginViewController ()

@end

@implementation LoginViewController

- (void)initViewsAndLayout
{
   _loginView = [[UIView alloc] init];
   _loginView.frame = self.view.bounds;
   [self.view addSubview:_loginView];

   //...
}
@end

5 个答案:

答案 0 :(得分:3)

一些事情:

  1. 您的代码未使用您定义的属性
  2. 不要将私有属性放在.h文件中
  3. 请勿声明您的班级符合.h文件中的UITextFieldDelegate协议
  4. 至于属性应该是strong还是weak我更喜欢strong,但是因为您要将这些属性(视图)中的每一个添加到视图控制器的视图中,将它们设为weak会很好,因为只要视图控制器处于活动状态,就会始终存在对它们的引用。

    你的.h应该是:

    @interface LoginViewController : UIViewController
    @end
    

    你的.m应该是(假设你确实想使用这些属性):

    @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
    

答案 1 :(得分:1)

当你使用strong属性时,你基本上是在编写retain,就像在,你希望Objective-C为属性分配内存并保持它直到它被释放。

这都是强有力的手段。

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

  

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

如果它们是对象而不是原语,那么是。

答案 2 :(得分:1)

如果您想手动创建属性而不使用xib或storyboard,我建议您使用strong属性创建属性。

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

因此,您最好使用强属性制作UIView的属性。

答案 3 :(得分:1)

作为一个简单的经验法则,

  1. 任何视图始终由其拥有(由强引用维护) superview,当它们被添加到superview时。
  2. 顶级视图始终由其VC拥有(由强引用维护)。
  3. 现在,可以通过两种不同的方式将视图添加到其超级视图中,

    • 从代码创建视图并使用addSubview:方法添加到某个超级视图时。 (这是你的问题所暗示的)。
    • 从nib文件加载视图层次结构时。 (此处还隐式addSubview:调用由UIKit创建以创建层次结构),因此子视图通过强引用保留各自的超视图。

    因此,在任何一种情况下,视图都会被其超级视图隐式保留,因此除非顶级视图自行处理,否则永远不会被处置。因此,声明子视图的strong属性会对子视图施加另一个所有权:

    • 其超级视图的隐式所有权,
    • 财产明确拥有。

    因此,通常,不需要为子视图声明strong属性,但是已经创建了它(来自nib / by code)。

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


    PS:

      

    使用故事板或笔尖创建视图时,我会连接我的   网点。据我所知,网点正在创造强大   连接到视图上的属性。

    我发现在你的问题中只有一种误解。从storyboard / nib创建视图时,outlet不会与属性创建任何所谓的strong连接。 IBOutlet仅描述属性如何加载视图。如果是outlet属性,则属性指向的视图将被取消存档并加载(如果尚未加载)。但是,其保留仍取决于strong / weak属性访问者。

答案 4 :(得分:1)

你问:

  

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

两部分答案:

  1. 视图控制器应明确保持对其顶级视图的strong引用。

    当完全不使用NIB或故事板并以编程方式执行所有操作时,根视图将在loadView中实例化,并且通常存储在retain / strong属性中。 UIViewController已经具有view属性,该属性具有retain内存语义,通常使用。 (有关以编程方式创建的视图的详细信息,请参阅 View Controller Programming Guide for iOS 资源管理视图控制器一章中的Creating a View Programmatically部分

    (如果您没有在loadView中创建根视图,而是使用NIB或故事板实例化根视图,并且只是以编程方式创建子视图,请不要担心上述讨论,因为NIB /故事板为您处理所有这些。)

  2. 对于子视图,当您调用addSubview时,视图将由其父视图保留。视图控制器也不必同时维护strong引用。你可以,但没有必要。

    在我看来,视图拥有其子视图,而不是视图控制器。如果从其父视图中删除了其中一个子视图,我认为视图控制器不应该保留它,并且我不得不记住nil视图控制器中的属性的好设计也是。更糟糕的是,如果我删除具有嵌套子视图的容器视图,我不想手动跟踪在视图控制器中设置所有这些单独的属性,我也需要nil

    不要误解我的意思:如果您需要/可以,可以将strong与子视图一起使用。但我认为暗示使用weak是不明智的是不正确的。