Article From:https://www.cnblogs.com/guohai-stronger/p/9496706.html

AutoreleaseThe mechanism is a member of iOS memory management. In MRC, it is called by calling.[obj autorelease]To delay memory release; in ARC, we don’t need to know Autorelease to manage memory well. And behind that, what does Objective-C do for us, and how to manage memory properly, let’s talk about AutoreLease mechanism, I hope you will have a better understanding of Autorelease!!!

 

AutoreleaseWhen will the object be released?

I don’t know if you’ve ever had such a problem during the interview, and I’ve met it in the world of pleasure. If you ask when the Autorelease object will be released for an interview, there are probably not many correct answers, and everyone will probably answer, “The current scope is large.Release the brackets at the end of the bracket. “If you answer like this, you obviously don’t have a good understanding of the Autorelease mechanism.

 

If there is no manual plus Autorelease Pool, the Autorelease object is in the current.runloopWhen the iteration is over, it will be released.The reason for the release is that the automatic release pool push and pop have been added to each runloop iteration.

(Each runloop will create a autoreleasepool and release it after the runloop iteration.

The following is a code about the use of autorelease between ARC and MRC, as follows:

// MRC
NSAutoreleasePool *pool = [NSAutoreleasePool alloc] init];
id obj = [NSObject alloc] init];
[obj autorelease];
[pool drain];

// ARC
@autoreleasepool {
  id obj = [NSObject alloc] init];
}

 

AutoreleaseApple implementation

We can see the implementation of apple Autorelease through Objective-C library runtime/objc-arr.mm.

class AutoreleasePoolPage 
    {
        static inline void *push() 
        {
            Equivalent to generating or holding NSAutoreleasePool class objects.}static inline void *pop(void *token)
        {
            Equivalent to discarded NSAutoreleasePool class objectsReleaseAll ();}static inline id autorelease(id obj)
        {
            AddObject class method equivalent to NSAutoreleasePool classAutoreleasePoolPage*autoreleasePoolPage = Get the AutoreleasePoolPage instance being used;AutoreleasePoolPage->add(obj);
        }
        id *add(id obj) 
        {
            Append objects to internal arrays}void releaseAll() 
        {
            Calling release instance method of object in internal array}};void *objc_autoreleasePoolPush(void)
    {
        return AutoreleasePoolPage::push();
    }
    void objc_autoreleasePoolPop(void *ctxt)
    {
        AutoreleasePoolPage::pop(ctxt);
    }
    id *objc_autorelease(id obj) 
    {
        return AutoreleasePoolPage::autorelease(obj);
    }

After the iOS program starts, the main thread creates a Runloop and creates it.Two Observer,The callback work is all around._wrapRunLoopWithAutoreleasePoolHandler()In the function.

The first Observer monitor isEntry(To enter Loop), callback is to create an automatic release pool in _objc_autoreleasePoolPush ().Priority is the highest, ensuring that the creation of the release pool is before all callbacks.

The second Observer listener has two events:BeforeWaiting(Invoking _objc_autoreleasePoolPop () and _objc_autoreleasePoolPush () to release the old release pool and create a new release pool when entering sleep;Exit(Exit Loop) call _objc_autoreleasePoolPop () to release the automatic release pool. This priority is the lowest, ensuring that the release pool is invoked after all callbacks.

 

Found through the above codeAutoreleasePoolPageIt is the core category:The function is mainly called.pushandpopMethod. Now let’s take a look at AutoreleasePoolPage.

 

AutoreleasePoolPage

Below is the AutoreleasePoolPage class:

#   define EMPTY_POOL_PLACEHOLDER ((id*)1)

#   define POOL_BOUNDARY nil
    static pthread_key_t const key = AUTORELEASE_POOL_KEY;
    static uint8_t const SCRIBBLE = 0xA3;  // 0xA3A3A3A3 after releasing
    static size_t const SIZE = 
#if PROTECT_AUTORELEASEPOOL
        PAGE_MAX_SIZE;  // must be multiple of vm page size
#else
        PAGE_MAX_SIZE;  // size and alignment, power of 2
#endif
    static size_t const COUNT = SIZE / sizeof(id);

    magic_t const magic;
    id *next;
    pthread_t const thread;
    AutoreleasePoolPage * const parent;
    AutoreleasePoolPage *child;
    uint32_t const depth;
    uint32_t hiwat;

Under ARC, if we use@autoreleasepool{}To create a AutoreleasePool, then the compiler will be changed to the following:

void *context = objc_autoreleasePoolPush();
// {}The code in it
objc_autoreleasePoolPop(context);

AutoreleasePoolPageIt is a class implemented by C++.

 

  • AutoreleasePoolThere is no single structure, and it is composed of a number of Autorelease PoolPages in a double-linked list, with the parent pointing to the previous page and the child pointing to the next page.
  • AutoreleasePoolPageEach of these objects opens up the size of a page of virtual memory (that is, 4096 bytes), which is used to store the address of the autorelease object except for the instance variable occupying space.
  • id *nextPointing to the next location of the top object of the stack.
  • If the Autorelease PoolPage space is full, an Autorelease PoolPage connection list is created, and subsequent objects are added to the new page.

Assuming that the current thread has only one AutoreleasePoolPage object, the memory address of the object is as follows:

As you can see from the above, when an object is sent,autoreleaseMessage,It is to add the current object to the top of the AutoreleasePoolPage stack and point next to it.

 

Release time

Every time an objc_autorelease PoolPush call is made, runtime adds the current Autorelease PoolPage to itSentinel objectIt will become the following structure:

objc_autoreleasePoolPushThe return value is the address of the sentinel object and is taken as a parameter by objc_autoreleasePoolPop. Therefore:

  1. According to the location of incoming sentinels, the page corresponding to the sentinel was found.
  2. Send a release message to all autorelease objects that are inserted later than the sentry object and move the next pointer to the correct location

 

Autorelease pools are composed of Autorelease PoolPages, which are double linked lists

popWhen the object is passed to the border, then the release message is sent to the object in page.

 

The above is the personal understanding of Autorelease mechanism, and I hope to help you!!!

Similar Posts:

Leave a Reply

Your email address will not be published. Required fields are marked *