Swift - Lazy Var vs. Allows programmatic creation of views (memory preservation)

I am a newbie and I understand that Lazy Var vs. Let. I noticed that it saves a ton of memory usage when using Lazy Var, especially with ImageViews. But the lessons and tutorials that I have seen so far do not often use Lazy Var, so I feel suspicious that this is bad practice and that I am missing something.

I did a little research and found out that Lazy is not "thread safe", but I donโ€™t understand what that means. I have seen many pros and cons, but I can not draw any conclusions, especially because I have very limited knowledge.

When everything is fine (or better) use Lazy Var vs. Let when creating a UIView?

lazy var profileImageView: UIImageView = { let imageView = UIImageView(image: #imageLiteral(resourceName: "page1")) imageView.translatesAutoresizingMaskIntoConstraints = false imageView.contentMode = .scaleAspectFit return imageView }() 
+6
source share
3 answers

Whether you will use lazy var or not depends on your code and its context. This is not bad or good in itself. You must decide when appropriate.

Before you can solve this, you must know what lazy var .

What is lazy var ?

Lazy initialization is a concept in which the initialization (construction) of a content variable is delayed until it is first used. The first access to such a variable starts initialization. Since the content is not created until the variable is used (necessary), using lazy initialized variables can save resources.

This is the main drive behind lazy initialization. You do not create something until you need it. This is also the logic that you will use when deciding whether something should be lazy var or not.

If you are dealing with representations (or anything else) that are always visible (necessary), it makes little sense to use lazy initialization. On the other hand, when you are dealing with instances that are not always needed, then using lazy var justified.

If your view is always displayed in the presented view controller, you cannot achieve more by making it lazy. If this is visible only under certain circumstances - for example, when the user expands some kind of folded panel, then making it lazy makes sense. This will make your view controller load faster and use less memory by default.


Regarding thread safety, lazy var are not thread safe in Swift.

This means that if two different threads try to access the same lazy var at the same time before such a variable is initialized, it is possible that one of the threads will gain access to a partially constructed instance.

For more information on thread safety, see:

Lift lazy var thread-safe?

Make "lazy var" threadsafe

+2
source

Another benefit of using lazy var is to improve the readability of your code.

In your example, the code associated with the image view is grouped together, rather than extending to the initializer, the setup function, or viewDidLoad . This improves local reasoning without requiring the code reader to take risks in different places in the code to understand how your presentation is tuned. To find out about their submission, they only need to go to its announcement.

Initialization closure, marked as lazy var , can access self , which allows you to do more configuration inside the closure, for example, add target actions or refer to other constant properties.

I would consider initializing properties (especially views) with closing as lazy var , to be good practice, and it seems to be gaining popularity in the Swift community as well.

Depending on the project, saving developer time can be much more valuable than saving system memory.

+3
source

Using pending variables can help circumvent a paradoxical problem: you want to create a custom view with subviews, the initialization of which refers to the parent view.

For example, if you want to create a subclass of UIView that contains a child UIScrollView of the same size, you cannot declare a class containing:

 var m_scrollView: UIScrollView override init(frame: CGRect) { m_scrollView = UIScrollView(frame: self.frame) super.init(frame: frame) } 

The compiler will complain that you are referencing yourself before calling super.init. But ... super.init should be called after all members are initialized.

Solving this circular problem makes m_scrollView lazy and initializes it in its declaration:

 lazy var m_scrollView = UIScrollView(frame: self.frame) 
0
source

Source: https://habr.com/ru/post/1273493/


All Articles