简体   繁体   English

为什么有些奥特莱斯是强有力的参考,即使文件规定出口应该是弱参考

[英]Why some Outlets are made strong references even tough the documentation specifies that outlets should be weak reference

Hi I am a newbie to iOS programming. 嗨,我是iOS编程的新手。 I know what a strong and weak reference is . 我知道强弱的参考是什么 But I get confused which type of reference to use when I have to deal with outlets. 但是当我不得不处理插座时,我会混淆使用哪种类型的参考。 After going through the documentation which states that 经过文件说明

Outlets should generally be weak, except for those from File's Owner to top-level objects in a nib file (or, in iOS, a storyboard scene) which should be strong. Outlets通常应该是弱的,除了那些从File的Owner到nib文件中的顶级对象(或者,在iOS中,故事板场景)应该很强。

So what I understood after going through the above statement is that the Outlets that we create should typically be weak by default . 所以我在完成上述陈述后理解的是,我们创建奥特莱斯默认情况下通常应该很弱

But while studying some tutorials I have come across the code where people have declared an outlet as strong reference . 但是在学习一些教程时,我遇到了一些代码,人们已经宣布了一个强大的参考 For example consider the following code : 例如,请考虑以下代码:

@interface AboutViewController : UIViewController

@property (nonatomic, strong) IBOutlet UIWebView *webView;

@end

The code : 代码 :

@property (nonatomic, strong) IBOutlet UIWebView *webView;

says that our AboutViewController has an UIWebView object . 说我们的AboutViewController有一个UIWebView对象

But why we need a strong reference here for the UIView object ?? 但是为什么我们需要一个强大的UIView对象参考 As the document states shouldn't this be an weak reference ? 正如文件所述,这不应该是一个弱的参考?

Also please explain in the documentation statement which I have quoted above what does the File's Owner to top-level objects mean?. 另外,请在上面引用的文档声明中解释文件所有者对顶级对象的含义是什么?

I have gone through many of the similar questions on this website but none of them helped me to clear my doubt. 我在这个网站上经历了很多类似的问题,但没有一个能帮我清除疑虑。 So please help. 所以请帮忙。 Thanks in advance :) 提前致谢 :)

What to use for non top level GUI elements - strong or weak - depends on how you are going to use their outlets. 非顶级GUI元素的用途 - 强或弱 - 取决于您如何使用他们的网点。 If you have a weak reference 如果你有一个弱参考

@property (nonatomic, weak) IBOutlet UIWebView *webView;

then after calling method 然后调用方法

[webView removeFromSupeview];

your webView will be nil and it will be impossible to restore UIWebView just by adding 你的webView将是零,只是通过添加来恢复UIWebView是不可能的

[self.view addSubview:webView];

If this is appropriate for you - it is better to use weak because you will free webView's memory when you do not need it. 如果这适合您 - 最好使用weak,因为当您不需要时,您将释放webView的内存。

On the other hand, in case of a strong reference after 另一方面,如果有strong参考后

[webView removeFromSupeview];

webView will still have referenceCount > 0 and webView will be deallocated only if owner will free it explicitly webView仍将具有referenceCount> 0,并且仅当所有者将显式释放它时才会取消分配webView

self.webView = nil;

or in the owner's 或者在主人的

- (void)dealloc

together with the owner itself. 与业主本人一起。

Usually there is no difference if you have static GUI. 通常,如果您有静态GUI,则没有区别。 If you want to remove (not hide) some views add be able to add them later - strong references should be used. 如果要删除(不隐藏)某些视图,可以在以后添加它们 - 应该使用强引用。

Top level objects should be retained strong. 顶级对象应保持强大。 Like 喜欢

@property(nonatomic,retain) UIView *view;

in UIViewController. 在UIViewController中。

It usually doesn't hurt to use a strong reference in place of a weak one in the case of outlets like this. 在这样的出口的情况下,使用强引用代替弱引用通常没有坏处。 And in some cases, you do need a strong reference. 在某些情况下,您需要一个强大的参考。

The idea is that something has to keep a strong reference to the object at all times or it could vanish. 这个想法是,某些东西必须始终保持对物体的强烈参考,否则它可能会消失。 If the object is a view that is a subview of another view, then that superview will keep a strong reference to it and so you can use a weak reference. 如果对象是另一个视图的子视图的视图,那么该超级视图将保留对它的强引用,因此您可以使用弱引用。 But, if you're going to do something else with that view, such as remove it from it's superview for some reason (maybe to reuse it elsewhere, or something), then you'll want to use a strong property so that there's always something holding it strongly. 但是,如果您要对该视图执行其他操作,例如出于某种原因将其从超级视图中删除(可能在其他地方重复使用,或者某些事情),那么您将需要使用强大的属性,以便始终持有它的东西。

Regarding the File Owner issue, that's because the top level object (most likely a view) does not have a superview holding on to it, so you need to use a strong property so that you're holding on to it. 关于文件所有者问题,那是因为顶级对象(很可能是一个视图)没有超级视图保留它,所以你需要使用一个强大的属性,这样你才能坚持下去。

The simple answer is that unless you are supporting iOS 5, outlets should always be strong. 简单的答案是,除非你支持iOS 5,否则网点应该总是很强大。

The purpose of weak outlets was so that in iOS5, if the system unloaded the view controller's view to save memory, any outlets pointing to subviews would be automatically released. 弱插座的目的是在iOS5中,如果系统卸载视图控制器的视图以节省内存,则任何指向子视图的插座都将自动释放。

In iOS 6 and later, the system never unloads the view controller's view (viewDidUnload is never called) because Apple found a way to release most of the memory used by a view without releasing the view itself. 在iOS 6及更高版本中,系统永远不会卸载视图控制器的视图(从不调用viewDidUnload),因为Apple找到了一种方法来释放视图使用的大部分内存而不释放视图本身。

Consequently, the outlets in a view controller will never normally need to be released until the view controller itself is released, at which point ARC will clean up all the outlets anyway. 因此,在视图控制器本身被释放之前,视图控制器中的插座通常不需要被释放,此时ARC将清理所有插座。

So just use strong for all your outlets and you won't have to worry about obscure bugs or compiler warnings due to using the wrong reference type. 因此,只需对所有商店使用strong,您就不必担心由于使用错误的引用类型而导致的模糊错误或编译器警告。

Quoting from Apple's Resource Programming Guide , 引用Apple的资源编程指南

Each time you ask the NSBundle or NSNib class to load a nib file, the underlying code creates a new copy of the objects in that file and returns them to you. 每次请求NSBundle或NSNib类加载nib文件时,底层代码都会在该文件中创建对象的新副本并将它们返回给您。 You need to ensure that you maintain the new object graph as long as necessary, and disown it when you are finished with it. 您需要确保在必要时维护新的对象图,并在完成后将其取消。 You typically need strong references to top-level objects to ensure that they are not deallocated; 您通常需要对顶级对象的强引用,以确保它们不会被释放; you don't need strong references to objects lower down in the graph because they're owned by their parents, and you should minimize the risk of creating strong reference cycles. 您不需要对图表中较低的对象进行强引用,因为它们由父母拥有,您应该尽量减少创建强引用周期的风险。

In case of framework classes like UIViewController the top-level object for the NIB file is the view property. 对于像UIViewController这样的框架类,NIB文件的顶级对象是view属性。 If you check in the documentation it is declared as retain (similar to strong ). 如果您签入文档,则将其声明为retain (类似于strong )。

@property(nonatomic, retain) UIView *view

So any subviews to this container view should be automatically owned by it. 因此,此容器view任何子视图都应由它自动拥有。 If you now declare these subview outlets as strong they will create a strong cycle and cause memory leaks when the framework tries to cleanup the container view . 如果您现在将这些子视图出口声明为strong那么当框架尝试清理容器view时,它们将创建一个strong循环并导致内存泄漏。 To avoid these strong cycles all subviews (or non top level objects) should be declared as weak properties. 为避免这些强循环,应将所有子视图(或非顶级对象)声明为weak属性。

When can you declare IBOutlet 's as strong 什么时候能宣布IBOutlet strong

Outlets should be changed to strong when the outlet should be considered to own the referenced object: 当插座应被视为拥有引用对象时,应将插座更改为强:

  • As indicated previously, this is often the case with File's Owner—top level objects in a nib file are frequently considered to be owned by the File's Owner. 如前所述,通常情况下,文件的所有者 - nib文件中的顶级对象通常被视为归文件所有者所有。
  • You may in some situations need an object from a nib file to exist outside of its original container. 在某些情况下,您可能需要来自nib文件的对象存在于其原始容器之外。 For example, you might have an outlet for a view that can be temporarily removed from its initial view hierarchy and must therefore be maintained independently. 例如,您可能有一个可以暂时从其初始视图层次结构中删除的视图的插座,因此必须单独维护。

You need to check in your code if webView object qualifies for case2 as above. 如果webView对象符合上述case2的条件,则需要检入代码。 If not the tutorial has got this one wrong and it actually should be weak . 如果不是教程已经错了,它实际上应该是weak

Hope that helps! 希望有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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