以前我一直在使用界面构建器创建我的视图。
使用故事板或笔尖创建视图时,我会连接我的网点。据我所知,这些网点正在与视图中的属性建立强大的联系。
如果我以编程方式创建视图,我的属性应该很强吗?
·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
答案 0 :(得分:3)
一些事情:
UITextFieldDelegate
协议至于属性应该是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)
作为一个简单的经验法则,
现在,可以通过两种不同的方式将视图添加到其超级视图中,
addSubview:
方法添加到某个超级视图时。 (这是你的问题所暗示的)。addSubview:
调用由UIKit创建以创建层次结构),因此子视图通过强引用保留各自的超视图。因此,在任何一种情况下,视图都会被其超级视图隐式保留,因此除非顶级视图自行处理,否则永远不会被处置。因此,声明子视图的strong
属性会对子视图施加另一个所有权:
因此,通常,不需要为子视图声明strong
属性,但是已经创建了它(来自nib / by code)。
但是,在某些特殊情况下,可能需要声明视图的strong
属性。例如,当应删除视图并将其重新添加到其superview时,应将视图声明为strong。当从超级视图中删除此类视图时,超级视图也会释放其所有权。因此,如果我们需要再次将同一视图重新分配给某个超级视图,我们需要保持该视图的强引用。在这种情况下,对视图的strong
属性引用变得很方便,并且它不允许释放视图。
PS:
使用故事板或笔尖创建视图时,我会连接我的 网点。据我所知,网点正在创造强大 连接到视图上的属性。
我发现在你的问题中只有一种误解。从storyboard / nib创建视图时,outlet不会与属性创建任何所谓的strong
连接。 IBOutlet
仅描述属性如何加载视图。如果是outlet属性,则属性指向的视图将被取消存档并加载(如果尚未加载)。但是,其保留仍取决于strong
/ weak
属性访问者。
答案 4 :(得分:1)
你问:
如果我以编程方式创建视图,我的属性应该是
strong
吗?
两部分答案:
视图控制器应明确保持对其顶级视图的strong
引用。
当完全不使用NIB或故事板并以编程方式执行所有操作时,根视图将在loadView
中实例化,并且通常存储在retain
/ strong
属性中。 UIViewController
已经具有view
属性,该属性具有retain
内存语义,通常使用。 (有关以编程方式创建的视图的详细信息,请参阅 View Controller Programming Guide for iOS 中资源管理视图控制器一章中的Creating a View Programmatically部分
(如果您没有在loadView
中创建根视图,而是使用NIB或故事板实例化根视图,并且只是以编程方式创建子视图,请不要担心上述讨论,因为NIB /故事板为您处理所有这些。)
对于子视图,当您调用addSubview
时,视图将由其父视图保留。视图控制器也不必同时维护strong
引用。你可以,但没有必要。
在我看来,视图拥有其子视图,而不是视图控制器。如果从其父视图中删除了其中一个子视图,我认为视图控制器不应该保留它,并且我不得不记住nil
视图控制器中的属性的好设计也是。更糟糕的是,如果我删除具有嵌套子视图的容器视图,我不想手动跟踪在视图控制器中设置所有这些单独的属性,我也需要nil
。
不要误解我的意思:如果您需要/可以,可以将strong
与子视图一起使用。但我认为暗示使用weak
是不明智的是不正确的。