We often see the following code in the official documents:
- MyClass.h
-
- @interface MyClass : NSObject {
- MyObject *myObject;
- }
- @property (nonatomic, retain) MyObject *myObject;
- @end
-
- MyClass.m
-
-
- @synthesize myObject;
-
- -(id)init{
- if(self = [super init]){
- MyObject * aMyObject = [[MyObject alloc] init];
- self.myObject = aMyObject;
- [aMyObject release];
- }
- return self;
- }
Create a Student class that inherits the NSObject class. Code:
- #import <Foundation/Foundation.h>
-
- @interface Student : NSObject{
-
- NSString *idd;
- NSString *name;
- }
- @property (nonatomic, retain) NSString *idd;
- @property (nonatomic, retain) NSString *name;
-
- @end
. M file code:
- #import "Student.h"
-
- @implementation Student
- @synthesize idd,name;
-
- - (void)dealloc
- {
- [idd release];
- [name release];
- [super dealloc];
- }
-
-
- @end
Use @ propety @ synthesize to implement the set get method of the member attribute of Student. Generally, we access the attributes of Student members in other classes:
Get the student name through student. name: assign a value to the name [student setName: @ "jordy"]. student is a Student class object. If you access its member attributes within the Student class, use [self setName: @ "jordy"], access using self. name;
Note: Due to wordpress, the characters in the Code are automatically saved in Chinese format. Remember to change the format to English when using it.
In Student. h and Student. m files are our habitual writing method, but it still does not seem to be able to explain the difference between adding self and not adding self. Please refer to the following code, which is another habitual writing method, take the Student class as an example:
. H file code:
- #import <Foundation/Foundation.h>
- @interface Student : NSObject{
-
- NSString *_idd;
- NSString *_name;
- }
- @property (nonatomic, retain) NSString *idd;
- @property (nonatomic, retain) NSString *name;
- @end
. M file code:
- #import "Student.h"
-
- @implementation Student
- @synthesize idd = _idd;
- @synthesize name = _name;
-
- - (void)dealloc
- {
- [_idd release];
- _idd = nil;
- [_name release];
- _name = nil;
- [super dealloc];
- }
- @end
It can be noted that the above Code, with the previous code, is changed to the _ name variable in the. h file; the @ sythesize Writing Style in the. m file has also changed.
If the self. _ name: Get the attribute value. The xcode compiler will prompt an error. In fact, this shows that we usually use self. name actually uses the get method of the student class name, and the same is true for the set Method of name.
Some people ask why such a complicated assignment is required? Why should I add self .? Directly write self. myObject = [[MyObject alloc] init]; isn't it true? Sometimes it seems that it is normal to not add self?
Next, we will explain the difference between using self and not using self from memory management.
Now let's take a look at the memory management content:
ViewController. h file, using the Student class, the Code is as follows:
- #import <UIKit/UIKit.h>
- @class Student;
-
- @interface ViewController : UIViewController{
-
- Student *_student;
- }
-
- @property (nonatomic, retain) Student *student;
-
- @end
ViewController. m file, code:
- #import "ViewController.h"
- #import "Student.h"
-
- @implementation ViewController
- @synthesize student = _student;
-
- - (void)didReceiveMemoryWarning
- {
- [super didReceiveMemoryWarning];
- }
-
- #pragma mark - View lifecycle
-
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- }
-
- - (void) dealloc
- {
- [_student release];
- _student = nil;
- [super dealloc];
- }
Other methods are not used, so they are not displayed here.
Create a Student class object in the viewDidLoad method of ViewController. m.
- Student *mystudent = [[Student alloc] init];
- self.student = mystudent;
- [mystudent release];
This is something I believe someone may have a question about. If it is so complicated to create a student object, it seems that self is directly used. student = [[Student alloc] init]; is there no problem either. It is quite normal to not add self?
Next we need to analyze the differences between them from the memory perspective:
First look at the indirect assignment:
1. Add self.
- MyObject * aMyObject = [[MyObject alloc] init]; //aMyObject retainCount = 1;
- self.myObject = aMyObject; //myObject retainCount = 2;
- [aMyObject release];//myObject retainCount = 1;
2. Do not add self.
- MyObject * aMyObject = [[MyObject alloc] init]; // aMyObject retainCount = 1;
- MyObject = aMyObject; // myObject retainCount = 1;
- [AMyObject release]; // the object has been released
Let's look at the directly assigned values:
3. Add self.
- self.myObject = [[MyObject alloc] init]; //myObject retainCount = 2;
4. Do not add self.
- myObject = [[MyObject alloc] init]; //myObject retainCount = 1;
Is it a bit dizzy now, let's change the code first, a common official method:
- MyClass.h
- @interface MyClass : NSObject {
- MyObject * _myObject;
- }
- @property (nonatomic, retain) MyObject *myObject;
- @end
- MyClass.m
- @synthesize myObject = _myObject;
OK. Try again now. If you use self. _ myObject = aMyObject; or myObject = aMyObject; you will get an error. Why? This is related to the Obj-c access method. to put it simply, we all know that @ property (nonatomic, retain) MyObject * myObject; is used to set an access method for an attribute, but the method name and attribute name we use are the same at ordinary times, now you have written it into different names, and it will be clear. _ myObject is the property and myObject is the name of the access method.
Now we know that self is the access method for access attributes. How does the access method work? Self. myObject = [[MyObject alloc] init]; why is memory leakage?
I will not explain nonatomic much about it. It is not the focus of my talk, and I have not fully figured it out and won't mislead everyone. I only talk about assign, retain, copy.
The get method is:
- -(MyObject*)myObject{
- return _myObject;
- }
The Set method is:
- // assign
- -(void)setMyObject:(id)newValue{
- _myObject = newValue;
- }
- // retain
- -(void)setMyObject:(id)newValue{
- if (_myObject != newValue) {
- [_myObject release];
- _myObject = [newValue retain];
- }
- }
- // copy
- -(void)setMyObject:(id)newValue{
- if (_myObject != newValue) {
- [_myObject release];
- _myObject = [newValue copy];
- }
- }
In fact, there are other content in these methods, not just these. And these methods can be rewritten. For example, if you write
- -(MyObject*)myObject{
- return _myObject;
- }
Put it in your class. When you call self. myObject (do not place it on the left of the equal sign, that will call the get method), this method will be called.
Here, I would like to say that @ property sets an access method for you. It has nothing to do with your properties. You can write only one sentence.
- @property (readonly) NSString *name;
Implement in your class
- -(NSString*)name{
- NSLog(@"name");
- return @"MyClass";
- }
You can also use self. name to call.
Now let's go back and talk about the four assignments we started. in this case, only a general value is assigned. Assigning a pointer to another pointer does not affect the allocated memory. Therefore, do not [aMyObject release] in 2. this sentence is the same as 4. I will not talk about it here. let's look at 1 and 3,
When setMyObject: method is called, newValue is retaken. We must release the original newValue. Otherwise, the memory will be leaked. In 1, we have a aMyObject that can be released. In 3, we cannot release it. Therefore, in 3, we will add a retainCount. memory leakage.
After talking about this, I just want to let everyone know what is the call property itself and what is the call access method. how can we avoid Memory leakage? In the above example, it is called in your own class. If this class is called by another class, pay more attention to it,
By the way, if you want to access object attributes in other classes, instead of using the access method, you can use myClass-> myObject to access the object directly, however, you must first set myObject to @ public. but this is not officially promoted,
The code is relatively simple. I still sent it out, so high people can ignore it.