Disputes during iOS development (I): disputes during ios development
Preface
I plan to share some controversial topics and express my views. This is the first article in this series. I want to discuss how to define the member variables of the class?
In the early days of Objective-C, Private member variables of classes can only be defined in. h header files. As follows:
@interface ViewController : UIViewController { @private NSInteger _value;}
Later, Apple improved Objective-C by adding an extension of the current class in. m, that is, a Category with no name, to add a member variable of the class. As follows:
@interface ViewController ()@property (nonatomic) NSInteger value;@end
The advantage is that these variables are completely hidden in the header file and do not need to be exposed to the user.
Next, in the 2013 WWDC, Apple further improved Objective-C, allowing
@implementation
Directly add private member variables of the class. As follows:
@implementation ViewController { NSInteger _value;}
As a result, we have differences on how to define private member variables. Many people prefer to use anonymous Category to define private member variables. However, I personally recommend@implementation
Directly add private member variables of the class. I will give some explanations below.
Historical Reasons
First, early iOS programmers must know that before the launch of ARC in 2011, Objective-C needs to manually manage reference counts. For all private members of the classself.property
The compiler can automatically generate code for us to manage the reference count. This feature still needs to be used before January 1, 2012.@synthesize
Keyword. Therefore, Apple recommends and emphasizes the useself.property
Programming habits to avoid problems in memory management. In the ARC era, the advantage of this programming habit no longer exists, because the compiler will automatically manage the reference count for us, and we only need to care not to cause loop reference problems.
Worry-free
I just mentioned that it is fully used in classes._property
To access private member variables, there will be no memory management issues. Howeverself.property
Is there no memory management problem when accessing private variables? Yes, but one thing to note: We 'd better not use it in init and dealloc.self.property
To access member variables, which is written in Apple's official documentation. I have also introduced it in my previous articles. (See: Do not use accessor in init and dealloc functions.)
So, if you useself.property
To access private member variables. Note that this method is not used in init and dealloc. This is actually a burden for programmers. You need to keep reminding yourself whether you have made any mistakes. If you use_property
To access private member variables.
About hide
As you know,self.property
Actually, the class is called.[self property]
Method, so there is actually a hidden layer of method calling. Many times, when we need to delay the first time a class member is made, the initial method of this Member will be written in this[self property]
Method implementation.
So the question is, when you are reading other people's code, you can seeself.property
You will think: Will there be some hidden function implementations? So you need to jump to its method implementation to find. However, in actual development, most of the property actually uses the Getter and Setter Methods automatically generated by the compiler, so you will not find the implementation. At this time, you will know: "Oh, in the past, this code did not have a custom member for chemical engineering ".
By default, this type of information is hidden in the code, which affects the reading and maintenance of the Code. In fact, most of the class member variables need to be assigned values in the class's first-made method. Most of the UIViewController member variables needviewDidLoad
Method. In this case, it is better to directly usesetupProperty
Method. The advantage is that the Code is more readable,self.property
It is used only when a delay is required.
There is another story about this. I previously reviewed a colleague's iOS code. That colleague liked to encapsulate table view data into another class, in my opinion, the data is actually an array and there is no need to encapsulate it. In the end, we have been arguing for a long time. In my opinion, all hiding is an increase in Code complexity, unless it brings benefits, such as code reuse and improved code maintainability. Otherwise, encapsulation with no benefits will only bring cost to code reading and comprehension. In my current experience, most of the table view data can be stored in an array, and there is no need to encapsulate this array. In addition, we provide a set of methods to operate on this array data.
Simple code is easier to read
_property
Write Ratioself.property
Shorter and simpler. I think the code written in this way is easier to read.
Faster execution speed and smaller IPA size
I have never imagined that the speed and application volume between the two will be very different. However, a peer (from a famous foreign social network company) told me that their company found that there is still a small gap between the two. If your application needs to be optimized in depth, considerself.property
Change_property
. However, I think most applications do not need to perform such in-depth optimization.
KVO and KVC
Yes, if you use_property
In this way, KVO and KVC cannot be used. But I have to ask, is it a good design for KVO's own private member variables within a class? We want to talk about classes with "High Cohesion and low coupling". KVO aims to implement the observer mode and decouple objects. If we use KVO inside the class and KVO's own private members, I think this is not a good design.
Computed Properties
In Swift, the concept of Computed Properties is introduced. In fact, this is also available in Objective-C, but it is not specifically named. If a property provides the correspondingsetter
Andgetter
And does not directly use its corresponding _ property variable, so this property is called Computed Properties.
Yes, if you use_property
And cannot use Computed Properties, but I don't think this has much impact. In fact, Computed Properties is a layer of encapsulation of data access. We also implement two functions that correspond to the datasetter
Andgetter
Function to achieve the same effect.
Circular references
Using private variables directly has a special point to note, which can be written directly in the block._property
Equivalentself->_property
, Although no self is written, it implies a retain for self, which may easily cause loop reference. Remember to use the weakSelf/strongSelf method, which is indeed ignored by many people.
Conclusion
In fact, the problems I mentioned above are all small issues with little impact. However, the unification of the Code style is a big problem. So whether your project is usingself.property
Style or_property
Style is not a problem, but if you use both styles at the same time, it will be very bad.