Some NSArray, NSDictionary, NSSet-related algorithm knowledge, nssetnsdictionary

Source: Internet
Author: User

[Conversion] NSArray, NSDictionary, NSSet-related algorithm knowledge, nssetnsdictionary

Several collection classes in iOS programming: NSArray, NSDictionary, NSSet, and corresponding Mutable versions should be used by everyone. If it is simple to use, I believe no one will make mistakes, but to be efficient (time complexity) accurate (Business accuracy), you also need to understand the hidden algorithm knowledge.

The use of collection classes in projects is almost inevitable. The Use Cases of collection classes can be abstracted and classified. In most cases, we need to temporarily save several objects for subsequent business logic operations, "Save and operate", or "Save and fetch 」, the terms corresponding to the computer world are read and write. During initial storage, we Insert data, and Get data next time we update data. We call Delete when we no longer need it. So you can see that there are so many operation scenarios in the Collection class, the key lies in the method we store, which is different from the method we take.

When we first learned data structures and algorithms, we knew that the data was organized in different ways, such as Array, List, Stack, Heap, and Tree. The corresponding read and fetch efficiency (time complexity) it is also different. If the insert efficiency is high, the efficiency of the next get operation will be low, such as unordered Array, O (1) during insertion, and O (N) during search ). If the search speed is fast, such as the sorted Array and the search speed is at O (logN), the attribute O (N) must be kept in an Array order during insertion ). Therefore, inserting and searching are fish and bear's paw. If you want to quickly find a book next time, you must spend more time organizing the bookshelves. Or we can jump out of the time dimension and use more space to make up for it. We can use a hash table or a Dictionary to store data. The search speed can be as fast as O (1 ), the disadvantage is that it sacrifices more space.

When Array is pre-stored, most of the scenarios are as follows:

Scenario 1

for (NSObject* obj in self.arr) {    //update each object}

Scenario 2

if ([self.arr containsObject:obj] == false) {    [self.arr addObject:obj];}

Scenario 3

if ([self.arr containsObject:obj] == true) {    [self.arr removeObject:obj];}

In the first scenario, there is not much to be explored. It takes O (N) to traverse a clean and profitable log ). The only thing to note is that you should not change the set object during traversal, such:

for (NSObject* obj in self.arr) {    if(obj.isInvalid){        [self.arr removeObject:obj];    }}

If you want to delete a file during traversal, you can use another method, for example:

for (int i = self.arr.count-1; i > 0; i --) {    NSObject* obj = self.arr[i];    if (obj.isInvalid) {        [self.arr removeObject:obj];    }}
Scenarios 2 and 3 need special attention. containsObject and removeObject both involve an important concept in a set, that is, equality.

The equality of values is very simple. You don't have to think about it to get an intuitive answer, for example, 1 = 1, 2.0f = 2.0f.

Object equality is not that simple. When do we think the two objects are equal? We can understand equality from two dimensions.

The same object is equal:

Theoretically, if the pointers of two objects point to the same memory area, they must be equal and point to the same object. In this case, we determine that equality is achieved through

if (obj1 == obj2)
Business attributes are equal:

Even if two objects do not point to the same memory area, all their (or some key) properties are equal. We can also think that these two objects are equal, for example, when a UserProfile object is connected, their name, gener, and age attributes are equal. at the business level, we can think that they are equal, in this case, we cannot use = to judge equality. We need to overload isEqual or implement isequtoxxx by ourselves:

@implementation MyObject- (BOOL)isEqual:(id)object{    if (self == object) {        return true;    }    if ([object isKindOfClass:[self class]] == false) {        return false;    }        MyObject* myObject = object;    if ([self.name isEqualToString:myObject.name]) {        return true;    }        return false;}@end

So when we determine whether the objects in the two sets are equal, we must be clear in our mind that they are equal. When containsObject and removeObject are called, if isEqual is reloaded, the system uses our isEqual method to judge equality. If there is no reload, then the system will judge the equality by judging the memory address.

In some architectures, the model layer design allows multiple copies of the same business object at the application layer. In this case, when using equality in the Array, pay special attention to the overload of the isEqual method. Of course, some mode layers only allow one copy. A business object always corresponds to only one memory address, and the isEqual method becomes redundant.

Another method supporting isEqual, hash, is also frequently mentioned. Official documents even stipulate that isEqual and hash must be implemented simultaneously. After learning the hash table, we know that if the two objects are equal in business, their hash values must be equal. The use of the hash method is to judge equality, the default hash method returns the memory address of the object. The problem is that we already have the isEqual method to judge equality. Why do we still need a hash?

The answer is that hash can determine whether an object exists in a set more efficiently and quickly. In NSArray, We need to traverse the Array and call isEqual N times to know whether the object exists in the set, the time complexity is O (N ). Before calling isEqual, you can call hash to determine whether it is equal. If the hash value is not equal, it is not necessary to call isEqual. If the hash value is equal, you must call isEqual again to check whether it is truly equal. But why is hash more efficient than isEqual? You can see the hash statement.

- (NSUInteger)hash{    return [_name hash];}

The Return Value of the hash method is an NSUInteger, which is usually directly related to the storage location of the object in the memory. That is to say, we can use this value to take O (1) the complexity of Array is faster than Array O (N). Array obviously does not have this feature, the elements in Array are continuously discharged in a piece of memory space, which has nothing to do with the return value of hash.

However, there is a premise for this convenience of using hash: the object is unique in the set, that is, duplicate elements, such as NSDictionary and NSSet, are not allowed in the set. When we use the following methods:

[dictionary objectForKey:key];[set addObject:object];
To ensure uniqueness, you must first determine whether an object exists in a set. An efficient judgment mechanism is very important at this time, that is, where hash plays a role, this is why NSArray only calls
The reason why NSDictionary and NSSet call hash frequently is used.

Therefore, when we use NSDictionary and NSSet, reloading the isEqual and hash methods is crucial to performance. The selection of the hash method does not need to be overly picky. It performs operations on key properties to ensure that the hash values are different in most scenarios. After all, after calling the hash method, isEqual will be called for further judgment, it does not affect the accuracy of our business.

Several key collection classes in Objective C: NSArray, NSDictionary, and NSSet are not as simple as they seem to be. When the elements in the Collection class reach a certain level, it is necessary to consider the algorithm efficiency behind it, which is why the importance of algorithms for programmers has always been emphasized.

Conversion from: knowledge about NSArray, NSDictionary, and NSSet Algorithms

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.