I plan to share some controversial topics and express my views. This is the first article in the series. What I want to discuss is: How should the member variables of a class be defined? In the early days of Objective-C, private member variables of a class could only be defined in the .h header file, as follows:
Later, Apple improved Objective-C, allowing a special anonymous Category to be added to the .m file, that is, a Category without a name, to implement the addition of class member variables, as follows:
The advantage of this is that these variables are completely hidden in the header file and do not need to be exposed to users. Then, in WWDC 2013, Apple further improved Objective-C, allowing private member variables of a class to be added directly in the @implementation of .m, as follows:
Therefore, there is a disagreement on how to define private member variables. Many people like to use anonymous Category to define private member variables. However, I personally recommend adding private member variables of the class directly in @implementation. Let me explain. Historical reasons First of all, early iOS programmers must know that before ARC was launched in 2011, Objective-C needed to manually manage reference counts. By using self.property for all private members of a class, the compiler can automatically generate code to manage reference counts for us. Before 2012, this feature still needed to be enabled using the @synthesize keyword. Therefore, Apple recommended and emphasized the programming habit of using self.property in the code standards to help everyone avoid problems in memory management. In the ARC era, the advantages brought by this programming habit no longer exist, because the compiler will automatically manage reference counts for us, and we only need to worry about not causing circular reference problems. Save time and trouble Just now I mentioned that if you use _property to access private member variables in a class, there will be no memory management problems. But will using self.property to access private variables also have no memory management problems? It is true, but there is one thing to note: we should never use self.property to access member variables in init and dealloc. This is written in Apple's official documentation, and I have also introduced it in my previous article. (See: "Don't use accessor in init and dealloc functions") So, if you use self.property to access private member variables, you need to be careful not to use this method in init and dealloc. This is actually a burden for programmers, and you need to constantly remind yourself if you have made a mistake. If you use the full _property method to access private member variables, you don't have to think about this kind of problem. About hiding As we all know, self.property actually calls the [self property] method of the class, so there is actually a layer of hidden method call. Many times, when we need to delay the initialization of a class member, we will write the initialization method of this member in the implementation of this [self property] method. So here comes the question, when you are reading someone else's code and see self.property, you will wonder: Is there some hidden function implementation here? So you need to jump to its method implementation to find it. But in actual development, most properties actually use the getter and setter methods automatically generated by the compiler, so you will not be able to find the implementation. At this time, you will realize: "Oh, it turns out that this code does not do the custom member initialization work." This default is hidden in the code more, which will affect the reading and maintenance of the code. In fact, most class member variables need to be assigned in the class initialization method, and most member variables of UIViewController need to be assigned in the viewDidLoad method. In this case, it is better to use a method called setupProperty to initialize directly in the corresponding method. The advantage of this is that the code is more readable, and self.property is only used when the initialization needs to be delayed. There is another story about this. I reviewed a colleague's iOS code before. That colleague likes to encapsulate the table view data into a class. I think that this data is actually an array, and there is no need to encapsulate it. In the end, we argued for a long time. My point of view is that all hiding will increase the complexity of the code, unless it brings benefits, such as achieving code reuse and improving code maintainability. Otherwise, encapsulation without benefits will only bring costs to code reading and understanding. In my current experience, most of the table view data can be placed in an array. There is no need to encapsulate this array and provide a set of methods to operate this array data. Short code is easier to read _property is shorter and simpler than self.property. I think it makes the code easier to read. Faster execution and smaller IPA size I never thought that there would be a big difference in speed and application size between the two. However, a colleague (from a well-known foreign social network company) told me that their company found that there is still a big gap between the two. If your application needs some deep optimization, you can consider replacing self.property with _property. But I think that most applications should not need such deep optimization. Key-Value Observation and Key-Value Context Yes, if you use _property, you can't use KVO and KVC. But I have to ask, is KVO's own private member variables inside a class a good design? We say that classes should have "high cohesion and low coupling". KVO is to implement the observer mode and decouple objects from each other. If KVO is used inside a class, KVO's own private members, I think it is not a good design. Computed Properties In Swift, the concept of Computed Properties is introduced. In fact, this also exists in Objective-C, but it is not specifically named. If we provide a corresponding setter and getter for a property and do not directly use its corresponding _property variable, then this property is called Computed Properties. Yes, if you use the _property form directly inside the class, you can't use Computed Properties, but I think this has little impact. In fact, Computed Properties is just a layer of encapsulation for data access. We can achieve the same effect by implementing two additional functions, corresponding to the setter and getter functions of the data. Written in *** In fact, the problems I mentioned above are minor and have little impact. However, the unification of code style is a big problem. So whether you use the self.property style or the _property style in your project, it is not a big problem, but if you use both styles at the same time, it will be very bad. I hope that this article can help everyone understand the debate in this area, and I also hope that everyone can reach a consensus within the company on this point. |
<<: Testin Cloud Testing's 1 billion mobile game testing fund sets off a gaming conference
Many optimizers who have just started to work on ...
Xiao Ming's short video traffic monetization ...
The matter began with a platform turnover statist...
WeChat was officially launched in 2011. In 2020, ...
1. How to formulate an operation plan for a new a...
How much does it cost to develop an electrician m...
Preface To be honest, I haven't updated my bl...
Is it easy to develop a Huai'an makeup mini p...
Retention is when a user performs a desired actio...
2014 has gone far away from us. In the past year,...
The concept of User Growth (UG) originated from t...
Silk, rice, tea and soybeans are known as the fou...
When many companies are bidding, they require bid...
This article was reviewed by Zhao Wei, deputy chi...
According to the 2019 WeChat data report, the num...