The life cycle of weak We all know that weak refers to a weak reference, which does not increase the reference count of the object, and after the object it points to is released, the weak pointer will be set to nil. Weak references are usually used to deal with circular references, such as in the use of proxies and blocks, which are relatively more commonly used. I have a little understanding of the implementation of weak before, and I know its basic life cycle, but I don't know how it is implemented clearly. Today I read the explanation of __weak in "Advanced Programming in Objective-C" again, and I'll take a note here. Let's take the following line of code as an example: Code Listing 1: Sample code
When we initialize a weak variable, the runtime calls the objc_initWeak function. The declaration of this function in Clang is as follows:
The specific implementation is as follows:
The example code is converted into the compiler simulation code as follows:
So, what is done here is to initialize obj1 to 0 (nil) first, and then pass the address of obj1 and obj as parameters to the objc_storeWeak function. The objc_initWeak function has a prerequisite: object must be a valid pointer that has not been registered as a __weak object. And value can be null or point to a valid object. If value is a null pointer or the object it points to has been released, object is zero-initialized. Otherwise, object will be registered as a __weak object pointing to value. This should be done by the objc_storeWeak function. The function declaration of objc_storeWeak is as follows:
The specific implementation is as follows:
Let's look at what this code does by omitting the various lock operations in the source code. Before that, let's first understand the weak table and SideTable. The weak table is a weak reference table, implemented as a weak_table_t structure, which stores all weak reference information related to an object. Its definition is as follows (specifically defined in objc-weak.h):
Among them, weak_entry_t is an internal structure stored in the weak reference table, which is responsible for maintaining and storing all weak reference hash tables pointing to an object. Its definition is as follows:
The referent is the object being referenced, i.e. the obj object in the sample code. The following union stores all weak references to the object. As can be seen from the comments, when out_of_line is equal to 0, the hash table is replaced by an array. In addition, the addresses of all weak reference objects are stored in the address of the weak_referrer_t pointer. Its definition is as follows: typedef objc_object ** weak_referrer_t; SideTable is a class implemented in C++. Its specific definition is in NSObject.mm. Let's take a look at the definitions of some of its member variables:
RefcountMap refcnts, you should be able to guess what this is used for, right? It looks like a reference count or something. Haha, it seems to be, this thing stores the reference count information of an object. Of course, we will not explore it here, we are concerned about weak_table. This member variable points to the weak table of an object. Now that we know about the weak table and SideTable, let's look back at objc_storeWeak. First, we need to find the old object pointed to by the weak pointer:
Then get the SideTable objects related to the new and old objects:
Next, let the weak reference pointer point to the new object:
*** will return this new object:
This is the basic implementation of objc_storeWeak. Of course, when objc_storeWeak is called in objc_initWeak, the old object is empty, so the weak_unregister_no_lock operation will not be executed. When the object pointed to by the weak reference is released, how to deal with the weak pointer? When releasing an object, the basic process is as follows: Calling objc_release Because the reference count of the object is 0, dealloc is executed In dealloc, the _objc_rootDealloc function is called In _objc_rootDealloc, the object_dispose function is called Calling objc_destructInstance ***Call objc_clear_deallocating Let's focus on the last step. The specific implementation of objc_clear_deallocating is as follows:
We can see that in this function, the SideTable instance corresponding to the object is first retrieved. If the object has an associated weak reference, arr_clear_deallocating is called to clear the weak reference information of the object. Let's take a look at the specific implementation of arr_clear_deallocating:
This function first finds the weak_entry_t list corresponding to the object, and then sets the weak references to nil one by one. ***Clear the object records. Through the above description, we can basically understand the process of a weak reference from birth to death. From this process, we can see that the processing of a weak reference involves various table lookups, additions and deletions, which still consumes a certain amount of time. Therefore, if __weak variables are used in large quantities, it will have a certain impact on performance. So, when should we use weak? The advice given to us by "Objective-C Advanced Programming" is to use the __weak modifier only when avoiding circular references. In addition, clang also provides a lot of weak reference processing functions, such as objc_loadWeak, objc_destroyWeak, objc_moveWeak, etc. We can find relevant implementations in Apple's open source code. I will study them carefully when I have time. refer to "Objective-C Advanced Programming" 1.4: __weak modifier Clang 3.7 documentation – Objective-C Automatic Reference Counting (ARC) apple opensource – NSObject.mm Odds and Ends CAGradientLayer The CAGradientLayer class is used to draw a color gradient on its background color to fill the entire shape of the layer, including rounded corners. This class inherits from the CALayer class and is very convenient to use. Similar to the gradient processing in Quartz 2D, a gradient has a starting position (startPoint) and an ending position (endPoint). Between these two positions, we can specify a set of color values (colors, elements are CGColorRef objects), which can be two or more, and each color value corresponds to a location (locations). In addition, gradients are divided into axial gradients and radial gradients. Let's write an example to see the specific use of CAGradientLayer:
refer to CAGradientLayer Class Reference Handling Ineligible Devices in Xcode I changed to a new computer, installed Xcode 6.3, created a new certificate and profile, opened Xcode, and connected my phone. But then I found that the device was marked as Ineligible Devices and was not recognized. The situation is similar to the following picture: The computer is trusted, and the certificates and profiles are OK. I tried restarting Xcode and reconnecting the phone several times, but it didn't work. I just can't select the device. *** I selected the device in Product->Destination. But I still can't select it in the toolbar. I'm so frustrated. Please help. Hide the cursor of UITextField after iOS 7 After the new project only supports iOS 7, many things become much simpler, just like hiding the cursor of UITextField, with a simple sentence: textFiled.tintColor = [UIColor clearColor]; Usually when we use UIPickerView as our UITextField's inputView, we need to hide the cursor. Of course, if you want to change the cursor color, you can do the same. There is a legacy problem with this approach: usually when we use UIPickerView as the inputView of UITextField, we don't want to perform various menu operations (select all, copy, paste), but when we just want to set the tintColor of UITextField, we can still perform these operations, so additional processing is required. We can handle this problem like this: in textFieldShouldBeginEditing:, we set the userInteractionEnabled of UITextField to NO, and then in textFieldShouldEndEditing:, set this value back. As follows:
That's it. Of course, this is just one way we are currently using. There are other methods, just google or stackoverflow. Left alignment issue of Chinese text in UIAlertView after iOS 7 Before iOS 7, if we want to display the text in UIAlertView on the left, we can use the following code to handle it:
But unfortunately, after iOS 7, Apple doesn't allow us to do this. When we get the subviews of UIAlertView, we get an empty array and we can't get the label we want. What should we do? Three ways: tell the product manager and UED that this can't be implemented (of course, this will be despised, and people will say you are incompetent); write it yourself; find a third-party open source code. Hehe, but because of the tight schedule recently, I decided to tell them that it can't be implemented, haha. But I found an open source on github, Custom iOS AlertView, with a lot of stars. It looks good, I will study it carefully later. |
<<: Use UIVisualEffectView to add special effects to views
>>: About Tint Color Properties
[[121135]] Some truths about programmers. Includi...
In an era when smartphone use has become a daily ...
According to Indonesian media reports on November...
“This is a social APP that will subvert WeChat!” ...
With the continuous development of the APP indust...
It only costs $10 to offset the impact of 1 ton o...
Summary of advertising placement on 7 major chann...
U.S. renewable energy growth slows in 2022 as sup...
Reasons for freezing developer accounts and the p...
Recently, Li Xiang of CHJ Automotive Group offici...
From January to December 2019, a total of 14.9228...
Xiaomi's "Internet phone" concept h...
Regarding glasses, I often see people encounterin...
During our practice, we found that many companies...
Recently, the Tianzhou-3 cargo spacecraft re-ente...