Make writing a habit together! This is my first day to participate in the “Gold Digging Day New Plan · April More text challenge”, click to see the details of the activity.

Explore the list of published articles in the series, which interested students can browse:

First article | iOS attribute @ property detailed inquiry

The second | iOS understanding Block using and principle

The third article | iOS Category Category and extend the Extension and associated objects, rounding

The fourth article | iOS lock NSLock, commonly used @ synchronized the underlying implementation of explanation, etc

Article 5 | iOS to fully understand the Nullability

——- Start ——-

The introduction

During development, we often need to determine whether an object is the object we need to work with and whether it meets our requirements for further execution of the program. At this point, we need to use some methods to determine. == and isEqual: and other Equality judgment methods came into being.


Commonly used to introduce

isEqual:.isEqualToString:= =The difference between

  • = =:
  1. For basic data types, values are compared;
  2. For object types, check whether the memory addresses of two objects are equal. If they are equal, return YES. If they are not equal, return NO.
  • IsEqual: NSObject and its subclasses specify the isEqual: method to determine whether two objects are equal. In its basic implementation, the equality check simply determines the equality identifier as follows:

    - (BOOL)isEqual: (id)other {
        return self == other;
    }
    Copy the code

    However, some subclasses of NSObject override isEqual:, so they each redefine the criteria for equality:

    • If the most important thing about an object is its state, it is called a value type, and its Observable property is used to determine equality.

    • If the most important thing about an object is its identity, then it is called a reference type, and its memory address is used to determine whether or not it is equal.

    In the Foundation framework, each of the following subclasses of NSObject has its own implementation of equality checking, just look at their isEqualToClassName: method. When they are determined to be equal in isEqualToClassName:, objects of the corresponding type follow value semantics, and when two instances of them need to be compared, these advanced methods are recommended instead of using isEqual: directly. Specific classes and methods are as follows:

    • NSValue -isEqualToValue:
    • NSArray -isEqualToArray:
    • NSAttributedString -isEqualToAttributedString:
    • NSData -isEqualToData:
    • NSDate -isEqualToDate:
    • NSDictionary -isEqualToDictionary:
    • NSHashTable -isEqualToHashTable:
    • NSIndexSet -isEqualToIndexSet:
    • NSNumber -isEqualToNumber:
    • NSOrderedSet -isEqualToOrderedSet:
    • NSSet -isEqualToSet:
    • NSString -isEqualToString:
    • NSTimeZone -isEqualToTimeZone:

    Note: the isEqualToClassName: method does not accept nil as an argument, as the compiler warns if nil is passed, whereas isEqual: accepts (and returns NO if nil is passed).

  • IsEqualToString: NSString is a very special type. Let’s look at the following code:

NSString *a = @"Hello";
NSString *b = @"Hello";

// YES
if (a == b) {
    NSLog(@"a == b is Yes"); 
}

// YES
if ([a isEqual:b]) {
    NSLog(@"a isEqual b is Yes");
}

// YES
if ([a isEqualToString:b]) {
    NSLog(@"a isEqualToString b is Yes"); 
}
Copy the code

All three of the above statements are YES. Why is == also YES?

This is because Apple uses an optimization called String Interning. In this case, the created string is internally treated as a string literal. The runtime does not allocate different memory space for these strings.

Note: All of this is for statically defined immutable strings.

In addition, objective-C selector names are stored as resident strings in a shared string pool. This is an important optimization for languages that operate by passing messages back and forth. The ability to quickly check strings by whether Pointers are equal can have a significant impact on runtime performance.

  • Hashing

For object-oriented programming, the main use case of object equality checking is to determine whether an object is a member of a collection. To ensure speed of checking in NSDictionary and NSSet collections, subclasses with custom equality implementations should implement hash methods in a way that satisfies the following criteria:

  1. [a isEqual:a] [b isEqual:a]
  2. If objects are equal, then their hashes must also be equal: ([a isEqual:b] [a hash] == [b hash])
  3. However, the opposite is not true: that is, two objects can have the same hash value but are not equal to each other: ([a hash] == [b hash] ¬ [a isEqual:b])
  • Tagged Pointers

Tagged Pointer has the following three functions:

  1. Tagged Pointer Stores small objects, such as NSNumber, NSString, and NSDate.
  2. Tagged Pointer is no longer an address, but an actual value. Therefore, it is no longer a real object, it is just a pseudo-pointer, a 64-bit binary. Therefore, its memory is not stored in the heap and does not require malloc and free;
  3. Memory read efficiency increased by 3 times and creation speed increased by 106 times;

Both OS X and iOS use Tagged Pointer objects in 64-bit code. Tagged Pointer objects are not used in 32-bit code, although this is not impossible in principle. Objc4-818.2 /runtime/objc-internal. H

{
    // 60-bit payloads
    OBJC_TAG_NSAtom            = 0, 
    OBJC_TAG_1                 = 1, 
    OBJC_TAG_NSString          = 2, 
    OBJC_TAG_NSNumber          = 3, 
    OBJC_TAG_NSIndexPath       = 4, 
    OBJC_TAG_NSManagedObjectID = 5, 
    OBJC_TAG_NSDate            = 6,

    // 60-bit reserved
    OBJC_TAG_RESERVED_7        = 7, 

    // 52-bit payloads
    OBJC_TAG_Photos_1          = 8,
    OBJC_TAG_Photos_2          = 9,
    OBJC_TAG_Photos_3          = 10,
    OBJC_TAG_Photos_4          = 11,
    OBJC_TAG_XPC_1             = 12,
    OBJC_TAG_XPC_2             = 13,
    OBJC_TAG_XPC_3             = 14,
    OBJC_TAG_XPC_4             = 15,
    OBJC_TAG_NSColor           = 16,
    OBJC_TAG_UIColor           = 17,
    OBJC_TAG_CGColor           = 18,
    OBJC_TAG_NSIndexSet        = 19,
    OBJC_TAG_NSMethodSignature = 20,
    OBJC_TAG_UTTypeRecord      = 21,

    // When using the split tagged pointer representation
    // (OBJC_SPLIT_TAGGED_POINTERS), this is the first tag where
    // the tag and payload are unobfuscated. All tags from here to
    // OBJC_TAG_Last52BitPayload are unobfuscated. The shared cache
    // builder is able to construct these as long as the low bit is
    // not set (i.e. even-numbered tags).
    OBJC_TAG_FirstUnobfuscatedSplitTag = 136, // 128 + 8, first ext tag with high bit set

    OBJC_TAG_Constant_CFString = 136,

    OBJC_TAG_First60BitPayload = 0, 
    OBJC_TAG_Last60BitPayload  = 6, 
    OBJC_TAG_First52BitPayload = 8, 
    OBJC_TAG_Last52BitPayload  = 263,

    OBJC_TAG_RESERVED_264      = 264
}
Copy the code

Essentially, Tagged Pointer is an 8-byte 64-bit Pointer to a Tag + Data combination:

  • Tag is a special Tag used to distinguish between Tagged Pointer and object types such as NSNumber, NSDate, and NSString.
  • Data is the stored value of an object.

In terms of operation efficiency, many functions related to TaggedPointer type have been optimized by Apple, so the execution efficiency is particularly high. For details, you can search isTaggedPointer in the source code for further inspection.

Objc-runtimenew. mm objc-Runtimenew. mm objc-Runtimenew. mm objc-Runtimenew. mm objc-Runtimenew. mm

/*********************************************************************** * Tagged pointer objects. * * Tagged pointer objects store the class and the object value in the * object pointer; the "pointer" does not actually point to anything. * * Tagged pointer objects currently use this representation: * (LSB) * 1 bit set if tagged, clear if ordinary object pointer * 3 bits tag index * 60 bits payload * (MSB) * The tag index defines the object's class. * The payload format is defined by the object's class. * * If the tag index is 0b111, the tagged pointer object uses an * "extended" representation, allowing more classes but with smaller payloads: * (LSB) * 1 bit set if tagged, clear if ordinary object pointer * 3 bits 0b111 * 8 bits extended tag index * 52 bits payload * (MSB) * * Some architectures reverse the MSB and LSB in these representations. * * This representation is subject to change. Representation-agnostic SPI is: * objc-internal.h for class implementers. * objc-gdb.h for debuggers. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /Copy the code

Detailed introduction here will not translate, focus on:

  • 1 bit Indicates whether it is Tagged Pointer.
  • 3 bits Indicates the type.
  • 60 bits Load Data capacity refers to storing object data.

Note: this is not a detailed description of Tagged Pointer. If you are interested, you can Google Tagged Pointer. There are many excellent articles that describe Tagged Pointer in detail.

Since Tagged Pointer isa pseudo-pointer and not a real object, it does not have an isa Pointer. Therefore, when we print the isa Pointer corresponding to Tagged Pointer through the LLDB, an error message is displayed:

error: Couldn’t apply expression side effects : Couldn’t dematerialize a result variable: couldn’t read its memory

When the Isa Pointer similar to Objecttive -c needs to be used for Tagged Pointer, isKindOfClass and object_getClass can be called to determine and perform other operations.


Process knowledge

  • Understand the difference between “Pointers” and “pointer values” and between “direct reference” and “indirect reference.

The variable that stores the address of the variable is called “pointer variable”. Simply speaking, variable P stores the address of variable A, so P can be called a pointer variable, or p points to A. When we access variable A, the program first obtains the address corresponding to A, and then retrieves the value of A from the storage space corresponding to this address. This method is called “direct reference”.

And when we through p made a first according to the first p into p corresponding memory address, according to this address to the corresponding storage space to store content, its content is actually a address, and then according to this address to the corresponding storage space in the corresponding content, the content is the value of a, This method of finding the corresponding address of A through P is called indirect reference.

  • IOS memory partition:

Heap: Holds objects, objective-C objects created by new, alloc, C objects created by malloc. Managed by developers, dynamic allocation and release, memory discontinuous, relatively slow speed.

Stack: store local variables, function parameters, allocated and released by the system, continuous memory, relatively fast speed.

BSS segment: storage of uninitialized global variables and static variables, memory has always existed, the program is released by the system after the end.

Data section: store initialized global variables and static variables, constants. It belongs to static memory allocation, which is divided into read-only data segment (constant area) and read and write data segment, which is released by the system after the end of the program.

Code area: an area of program code used to hold code that is compiled into binary and stored in memory while the program is running.


conclusion

Equality is used frequently in daily development to judge and determine the running flow of the application. If the processing is not accurate, some unexpected bugs may occur. So mastering its use can help us avoid some very elementary mistakes. That’s all about iOS Equality. I hope this article will be helpful to you. Thank you for reading it.


References:

Implementing Equality and Hashing (www.mikeash.com/pyblog/frid…)

Equality (nshipster.com/equality/)


About The Technical Group

The iOS technology group is mainly used to learn and share the technology used in daily development, and keep learning and making progress together. The article repository is here: github.com/minhechen/i… Wechat official account: iOS Technology group, welcome to contact the group to learn and exchange, thank you for reading.