iOS weak and strong, lazy loading, and circular referencing

Source: Internet
Author: User

First, weak and strong

1. Understanding

When I first started to learn the UI, the weak and strong described most of them as "introduced by arc, weak equivalent to assign in OC, but weak is used to decorate objects, but they do not result in a reference count plus 1, whereas strong is equivalent to OC retain , it causes a reference count plus 1 ".

Arc principle: As long as there is a variable pointing to the object, the object will remain in memory. When the pointer points to a new value, or if the pointer no longer exists, the associated object is automatically freed. This rule is applicable for instance variables, synthesize attributes, and local variables.

The strong pointer maintains the life of the object, and an object that has a strong pointer to it will not be freed; Conversely, if there is no strong pointer pointing to it, it is automatically freed. Default all instance variables and local variables are stong pointers

A pointer variable of type weak can still point to an object, but not to the owner of the object. That is, when the object is destroyed, the weak pointer automatically points to nil (null pointer).

Mark Portal: MJ's analysis of weak and strong

2.weak and strong pointer use note

We often see that the properties referenced to the controller from Xib are weak pointers, why are those control objects not automatically freed?
@property (nonatomic,weak) ibooutlet UIButton *btn;

Uiviewcontroller->uiview->subview->uibutton
Enter into the UIViewcontroller.h file and discover
@property (null_resettable, Nonatomic,strong) UIView *view; The goods are strongly quoted.
So, the referential relationship above is that Xib is a strong reference to the button, and the property you declared is a weak reference to it.
@interface LZVC ()
@property (nonatomic,weak) UIView *myview; @end @implementation lzvc-(void) viewdidload { [super viewdidload];
A warning appears: ("warning:assigning retained object to weak variable; Object would be released after assignment ")
_myview = [[UIView alloc] initWithFrame:self.view.frame];
_myview.backgroundcolor = [Uicolor Redcolor];
[Self.view Addsubview:_myview];
} @end//We will find that _myview is not added to Self.view at all, because _myview is a weak pointer, without the ability to hold objects, The member variable initialized after its equals sign is automatically freed after it has just been initialized, so _myview gets empty because it is not referenced by a strong pointer.

Correction Method:

① change the weak in the member property declaration to strong. (Direct _myview strongly references the initialized object, so the initialized object will not be automatically freed)

② the place where the warning appears, change to the following:
Because all instance variables and local variables are strong-type pointers by default, MyView strongly references the initialized object and then _myview the weak reference MyView
UIView *myview = [[UIView alloc] initWithFrame:self.view.frame]; UIView *myview.backgroundcolor = [Uicolor Redcolor];_myview = MyView; [Self.view Addsubview:_myview];

3.weak and strong use time (according to the above characteristics, I do the following test)

1> I created a new subclass from UIView TestView, added a property text, rewritten its Dealloc method, I want to see when TestView released

@property (nonatomic,copy) nsstring *text;  Property
Rewrite Dealloc and print data-(void) dealloc{ NSLog (@ "%@----%s", self.text,__func__);

[Super Dealloc];}

2> in the controller, I wrote the following code

#import "LZVC.h" #import "TestView.h" @interface LZVC () @property (nonatomic,weak) TestView *myweakview;  Weakly quoted @property (Nonatomic,strong) TestView *mystongview;    Strong reference @end@implementation lzvc-(void) viewdidload {[Super viewdidload];        Self.view.backgroundColor = [Uicolor Whitecolor];    TestView *myweakview = [[TestView alloc] Initwithframe:cgrectmake (0, 64, 160, 160)];    Myweakview.backgroundcolor = [Uicolor Redcolor];    Myweakview.text = @ "I am a weak quote";    _myweakview = Myweakview;        [Self.view Addsubview:_myweakview];    TestView *mystrongview = [[TestView alloc] Initwithframe:cgrectmake (160, 64, 160, 160)];    Mystrongview.backgroundcolor = [Uicolor Greencolor];    Mystrongview.text = @ "I am a strong quote";    _mystongview = Mystrongview;    [Self.view Addsubview:_mystongview]; #pragma mark clicks on the screen trigger-(void) Touchesbegan: (Nsset<uitouch *> *) touches withevent: (uievent *) event{if (    Self.myweakview) {[Self.myweakview Removefromsuperview];  } if (Self.mystongview) {      [Self.mystongview Removefromsuperview]; }
}

3> Click on the screen, two views are removed from the screen, the following print, we found that the weak reference of the TestView was freed (through the Addsubviews,myweakview have a strong reference to the controller)

4> I go back to the home page so that this LZVC controller is destroyed, and there is a print, strong reference to the TestView (Mystrongview in addition to its strong reference to the controller, the declared properties are also strongly referenced)

5> Summary: I believe that from 3, 4 of the printing is clear, if you want a control's life cycle with your controller is destroyed to release, then use strong; If you just want it to be destroyed after being removed, use weak

Second, lazy loading

1. Lazy Loading

Lazy Loading--also known as deferred loading--is loaded when needed (low efficiency, small memory footprint). Lazy loading, in fact, is to rewrite the Getter method. The popular point is that in development, when the application needs to use the resources. Do not load resources when the program is started, and then load the resources only when they are running when some resources are needed.

We know that iOS devices have limited memory, and if you load all the resources that will be used in the future once the program is started, you may run out of memory on your iOS device. These resources such as a lot of data, pictures, audio and so on, so when we use lazy loading must be aware of the first to determine whether there is already, if not then to instantiate.

  2. Benefits of using lazy loading

1> do not have to write the code of the object in the Viewdidload method, the code is more readable

2> each control's getter method is responsible for the respective instantiation processing, the code is independent of each other, loosely coupled. It also makes non-null judgments to prevent objects from being repeatedly loaded

3> only when resources are really needed to load, saving memory resources, preventing objects from being created in advance, and preventing objects from being created when objects are used (memory optimizations such as memory-intensive operations such as loading plist files).

3. Initializing member variables with lazy loading

@interface LZVC () @property (Nonatomic,strong) Nsarray *datasource; @end @implementation lzvc#pragma Mark Lazy Loading-(Nsarray *) datasource{    if (_datasource = = nil) {        _datasource = @[@ "1", @ "2", @ "3", @ "4"];    }    return _datasource;} Finally, when using the Self.datasource form can be

Here, by the way, the question of member variables and attributes:

1> direct access to member variables: _datasource = @[@ "5" @ "6"];
Direct assignment, intuitive and fast.

2> Access member properties: Self.datasource = @[@ "5", @ "6"];
When the assignment is performed, the setter method is taken, and when the value is fetched, the getter method is used, and we can do something we want to do in these two methods (example: the data validity under the setter method, the change of the listening value, etc.) And the lazy loading in the Getter method can show its benefits.
Third, circular reference problem (scene)

1. Classic: Proxy mode delegate (Uitableviewdelegate) example

The controller's view strong reference TableView, and TableView delegate is the controller, if the following two agent properties with strong to decorate, will cause circular reference problems, The best way to solve this problem is to have one of the two weak references (weak).

@property (nonatomic, weak, nullable) ID <UITableViewDataSource> dataSource; @property (nonatomic, weak, nullable) ID <UITableViewDelegate> delegate;

The 2.NSTimer timer target causes a circular reference, and Nstimer holds the target object.

3.block is a member variable, and the self is accessed in the block and its properties cause a circular reference

iOS weak and strong, lazy loading, and circular referencing

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.