Different ways to implement locks in Objective-C (Part 2)

Different ways to implement locks in Objective-C (Part 2)

Different ways to implement locks in Objective-C (Part 2)

NSHashTable

When looking at the code of KVOController, I saw the NSHashTable class, so I sorted it out.

NSHashTable imitates NSSet (NSMutableSet), but provides more operation options than NSSet, especially in the support of weak reference relationships. NSHashTable is more flexible in object/memory processing. Compared with NSSet, NSHashTable has the following features:

NSSet (NSMutableSet) holds strong references to its elements, and these elements use hash values ​​and the isEqual: method to perform hash checks and determine whether they are equal.

NSHashTable is mutable, it has no immutable version.

It can hold weak references to elements and remove them correctly when the object is destroyed, which is not possible with NSSet.

Its members can be copied when added.

Its members can use pointers to indicate equality and perform hash checks.

It can contain arbitrary pointers, and its members are not restricted to objects. We can configure an NSHashTable instance to operate on arbitrary pointers, not just objects.

When initializing NSHashTable, we can set an initial option, which determines all subsequent behaviors of this NSHashTable object. This option is defined by the NSHashTableOptions enumeration, as shown below:

  1. enum {
  2.  
  3. //Default behavior, strong reference to objects in the collection, equivalent to NSSet  
  4. NSHashTableStrongMemory = 0 ,
  5.  
  6. // Before adding the object to the collection, the object is copied  
  7. NSHashTableCopyIn = NSPointerFunctionsCopyIn,
  8.  
  9. // Use shifted pointer to do hash check and determine whether two objects are equal;  
  10. // Also use the description method to make a description string  
  11. NSHashTableObjectPointerPersonality = NSPointerFunctionsObjectPointerPersonality,
  12.  
  13. // Objects in the weak reference collection will be removed correctly after the object is released.  
  14. NSHashTableWeakMemory = NSPointerFunctionsWeakMemory
  15. };
  16. typedef NSUInteger NSHashTableOptions;

Of course, we can also use NSPointerFunctions to initialize, but only by using the values ​​defined by NSHashTableOptions can we ensure that the various APIs of NSHashTable can work correctly—including copying, archiving, and fast enumeration.

I think NSHashTable is attractive because it can hold weak references to elements and correctly remove them after the object is destroyed. Let's write an example:

  1. // The specific calls are as follows  
  2. @implementation TestHashAndMapTableClass {
  3.  
  4. NSMutableDictionary *_dic;
  5. NSSet *_set;
  6.  
  7. NSHashTable *_hashTable;
  8. }
  9.  
  10. - (instancetype)init {
  11.  
  12. self = [ super init];
  13.  
  14. if (self) {
  15.  
  16. [self testWeakMemory];
  17.  
  18. NSLog(@ "hash table [init]: %@" , _hashTable);
  19. }
  20.  
  21. return self;
  22. }
  23.  
  24. - ( void )testWeakMemory {
  25.  
  26. if (!_hashTable) {
  27. _hashTable = [NSHashTable weakObjectsHashTable];
  28. }
  29.  
  30. NSObject *obj = [[NSObject alloc] init];
  31.  
  32. [_hashTable addObject:obj];
  33.  
  34. NSLog(@ "hash table [testWeakMemory] : %@" , _hashTable);
  35. }
  36.  
  37. The output of this code is as follows:
  38.  
  39. hash table [testWeakMemory] : NSHashTable {
  40. [ 6 ] <NSObject: 0x7fa2b1562670 >
  41. }
  42. hash table [init]: NSHashTable {
  43. }

As you can see, after leaving the testWeakMemory method, the obj object is released and the reference to the object in the collection is safely deleted.

It seems that NSHashTable is better than NSSet (NSMutableSet). Should we use NSHashTable in all applications? Peter Steinberger gave us a set of data in The Foundation Collection Classes, showing that in the operation of adding objects, NSHashTable takes almost twice as long as NSMutableSet, while in other operations, the performance is roughly the same. So, if we only need the features of NSSet, try to use NSSet.

In addition, Mattt Thompson also wrote a very interesting paragraph at the end of NSHash​Table & NSMap​Table, which I will quote directly here:

As always, it's important to remember that programming is not about being clever: always approach a problem from the highest viable level of abstraction. NSSet and NSDictionary are great classes. For 99% of problems, they are undoubtedly the correct tool for the job. If, however, your problem has any of the particular memory management constraints described above, then NSHashTable & NSMapTable may be worth a look.

refer to

NSHashTable Class Reference

NSHash​Table & NSMap​Table

NSHashTable & NSMapTable

The Foundation Collection Classes

Odds and Ends

(I) “Unknown class XXViewController in Interface Builder file.”

I recently wrote a XXViewController class in a static library, and then specified the xib class as XXViewController in the main project's xib. When the program was running, the following error was reported:

  1. Unknown class XXViewController in Interface Builder file.

I encountered this problem before, but I don’t remember it clearly, so I started looking for the answer on stackoverflow again.

In fact, this problem has nothing to do with Interface Builder. The most direct reason is that the related symbols are not loaded from the static library. The solution to this problem is to add the two flags "-all_load -ObjC" in the "Build Setting" -> "Other Link Flags" of the Target, and it will be OK.

(II) Dealing with Unbalanced calls to begin/end appearance transitions for …

One of our businesses has a requirement that after entering a list, a web page needs to be pushed immediately to promote some activities. On iOS 8, our implementation is OK; but on iOS 7, we found that this web page could not be pushed, and the console gave a warning message, as follows:

  1. Unbalanced calls to begin/end appearance transitions for ...

In this case, when you click the back button in the navigation bar, a black screen is displayed directly.

We checked on stackoverflow and found this tip:

  1. occurs when you try and display a new viewcontroller before the current view controller is finished displaying.

This means that an attempt is made to display a new view controller before the current view controller has finished displaying it.

So we checked the code and found that a network request was made in viewDidLoad, and after the request returned, the web event promotion page was pushed. At this time, the current view controller may not show completion (that is, the push operation was not completed).

  1. Basically you are trying to push two view controllers onto the stack at almost the same time.

When two view controllers are pushed to the current navigation controller stack almost at the same time, or two different view controllers are popped at the same time, uncertain results will occur. Therefore, we should ensure that there is only one operation on the same navigation controller stack at the same time, and we should not push or pop a new view controller even if the current view controller is animating.

So *** we put the data request of the web activity into viewDidAppear and did some processing, so the problem was solved.

<<:  IBOutletCollection

>>:  Use UIVisualEffectView to add special effects to views

Recommend

Short video marketing, save these strategies quickly!

In recent years, with the sharp increase in deman...

These copywritings have made me laugh for a year

1/Milk advertisement Copywriting : If you drink a...

How to evaluate, monitor and promote KOL marketing channel conversion?

With the rapid development of the Internet , we h...

Information flow advertising: characteristics and trends!

Feed ads are ads that are inserted into the updat...

BYD: BYD has applied for more than 48,000 patents worldwide

According to recent news, BYD released an announc...

Why would Google open source its most important secrets?

Google's technology is one of the main drivin...

Faraday Future says it has not yet raised $1 billion in "life-saving money"

On December 18, in response to media reports that...

The strange "Swallow in the Stone" is actually an ancient shellfish

In the Paleozoic Era, there was a thriving class ...

New media operation: How to create a "million-dollar" self-media matrix?

Many students would say: It’s 2020, can self-medi...