This paper mainly studies Tagged Pointer technology, and briefly discusses the problems to be solved by this technology and its value in practical application.

If you want to take a closer look at how Tagged Pointer is implemented, check out the Friday Q&A 2012-07-27: Let’s Build Tagged Pointers and objc source code.

In addition, please test the example codes involved in this article on a real iOS device, because Tagged Pointer technology is targeted at different platforms and the specific implementation details are different, otherwise the test results cannot be consistent with those in this article.

Object memory

Let’s take a look at objects in iOS and see TaggedPointer for the full code.

    __weak NSNumber *weakNumber;
    __weak NSString *weakString;
    __weak NSDate *weakDate;
    __weak NSObject *weakObj;
    int num = 123;
    
    @autoreleasepool {
        weakObj = [[NSObject alloc] init];
        weakNumber = [NSNumber numberWithInt:num];
        weakString = [NSString stringWithFormat:@"string%d", num];
        weakDate   = [NSDate dateWithTimeIntervalSince1970:0];
    }
    NSLog(@"weakObj is %@", weakObj);
    NSLog(@"weakNumber is %@", weakNumber);
    NSLog(@"weakString is %@", weakString);
    NSLog(@"weakDate is %@", weakDate);
Copy the code

In line 7, we first define four __weak*** objects and build an Autoreleasepool, so after line 12, all weak reference objects with __weak modifier are released. After the above analysis, we can see that the object prints null.

But, in fact, we get the following output.

TaggedPointer[3570:3928309] weakObj is (null) TaggedPointer[3570:3928309] weakNumber is 123 TaggedPointer[3570:3928309] weakString is string123 TaggedPointer[3570:3928309] weakDate is Thu Jan  1 08:00:00 1970

You can see that only the object value for NSObject is null, and all the other values are printed normally.

This is because NSNumber, NSString, and NSDate are using Tagged Pointer technology.

Second, the Tagged Pointer

2.1 Tagged Pointer Technology

2.1.1 profile

2.2.2 Tagged Pointer is Not introduced

2.2.3 Importing Tagged Pointer

2.2.4 Check whether it is Tagged Pointer

2.2 applications

2.2.1 Supported Object types

Objc supports Tagged Pointer as follows:

typedef uint16_t objc_tag_index_t;
enum
{
    OBJC_TAG_NSString          = 2, 
    OBJC_TAG_NSNumber          = 3, 
    OBJC_TAG_NSIndexPath       = 4, 
    OBJC_TAG_NSDate            = 6. };Copy the code

Tagged Pointer is supported for NSString, NSNumber, NSDate, and NSIndexPath.

2.2.2 NSNumber

We look at how Tag+Data is stored using NSNumber and NSString objects.

See TaggedPointer for an example code

As shown below, we created a number of NSNumber objects:

NSNumber *number1 = @1; //0xb000000000000012 NSNumber *number2 = @2; //0xb000000000000022 NSNumber *number3 = @(0xFFFFFFFFFFFFFFF); //0x1c0022560 NSNumber *number4 = @(1.2); //0x1c0024b80 int num4 = 5; NSNumber *number5 = @(num4); //0xb000000000000052 long num5 = 6; NSNumber *number6 = @(num5); //0xb000000000000063 float num6 = 7; NSNumber *number7 = @(num6); //0xb000000000000074 double num7 = 8; NSNumber *number8 = @(num7); / / 0 xb000000000000085 / / value: 0xb000000000000012 0xb000000000000022 0x1c0022560 0x1c0024b80 0xb000000000000052 0xb000000000000063 0xb000000000000074 0xb000000000000085 NSLog(@"%p %p %p %p %p %p %p %p", number1, number2, number3, number4, number5, number6, number7, number8);Copy the code

From the above table, we can conclude:

  • A large number that exceeds Tagged Pointer will be converted to object storage and stored on the heap.
  • If it is a floating point number with a decimal point, it will be stored directly as an object.
  • All other types of numbers, including floating-point and integer types without fractional parts, are stored as Tagged Pointer.

In addition, the Tagged Pointer storage format is as follows, using number1 as an example:

2.2.3 nsstrings

NSString handles the same logic as NSNumber.

NSString *str1 = @"a"; //0x1049cc248 NSString *str2 = [NSString stringWithFormat:@"a"]; //0xa000000000000611 NSString *str3 = [NSString stringWithFormat:@"bccd"]; //0xa000000646363624 NSString *str4 = [NSString stringWithFormat:@"c"]; //0xa000000000000631 NSString *str5 = [NSString stringWithFormat:@"cdasjkfsdljfiwejdsjdlajfl"]; //0x1c02418f0 NSLog(@"%@ %@ %@ %@ %@", [str1 class], //__NSCFConstantString [str2 class], //NSTaggedPointerString [str3 class], //NSTaggedPointerString [str4 class], //NSTaggedPointerString [str5 class]); // __NSCFStringCopy the code

Based on the above results, we classify NSString into three categories:

  • Constant type: __NSCFConstantString, a string constant defined.
  • TaggedPointer Type: NSTaggedPointerString: a short string created using an object method.
  • NSString object type: __NSCFString, including string objects created by NSString, NSMutableString, etc.

The above, sorted as follows:

NSString is stored in Tagged Pointer format as follows:

2.3 Memory Management

Three, a study of interview questions

The interview questions are as follows:

reference

link

  1. Friday Q&A 2012-07-27: Let’s Build Tagged Pointers
  2. Tagged Pointer wiki
  3. NSString retain count -1
  4. Objc source

The sample code

  1. TaggedPointer