Recently, I conducted a set of mock interview with BestSwifter and Kuailejim. However, no matter fresh graduates or senior engineers who have worked for two or three years, they are confused about the following questions. They may not be used much in development

  • Relationship between Autoreleasepool and Runloop
  • What objects under ARC are managed by Autoreleasepool
  • Child threads do not enable Runloop by default, so how to handle Autorelease objects? Will memory leak without manual processing?

The main thread enables RunLoop by default. The RunLoop automatically creates the Autoreleasepool and performs Push, Pop, and other operations for memory management

Second question, what objects under ARC are managed by Autoreleasepool? Most people say, “It will be managed by pool.” This is not the case, for ordinary objects it is Realease for us in place by the compiler. I’ve already summarized this issue: reference counting leads to a discussion that references the classic iOS and OS X multithreading and Memory Management book.

The third question is difficult to answer and requires a close reading of the source code for Runtime and Autoreleasepool. Does NSThread create autoreleasepool automaticly now? . Just to make it very simple again, if you create a Pool on a child thread, the Autorelease object that you create is going to be managed by the Pool. The autoreleaseNoPage method is called if you did not create a Pool but generated an Autorelease object. In this method, you will automatically create a HotPage for you. Call Page ->add(obj) to add the object to the stack of AutoreleasePoolPage. This means no manual memory management and no memory leaks. StackOverFlow authors also say that this feature was only added to OS X 10.9+ and iOS 7+. There is no official documentation for this, but you can read the source code. Post part of the source code here:

static __attribute__((noinline))
id *autoreleaseNoPage(id obj)
{
    // No pool inPlace. // hotPage can be understood as the AutoreleasePoolPage currently in use. assert(! hotPage()); // POOL_SENTINEL is just an alias for nilif(obj ! = POOL_SENTINEL && DebugMissingPools) { // We are pushing an object with no poolin place, 
        // and no-pool debugging was requested by environment.
        _objc_inform("MISSING POOLS: Object %p of class %s "
                     "autoreleased with no pool in place - "
                     "just leaking - break on "
                     "objc_autoreleaseNoPool() to debug", 
                     (void*)obj, object_getClassName(obj));
        objc_autoreleaseNoPool(obj);
        returnnil; } // Install the first page. // Create a hotpage for you AutoreleasePoolPage(nil);setHotPage(page);

    // Push an autorelease pool boundary if it wasn't already requested. // POOL_SENTINEL is just an alias for nil, the sentinel object if (obj! = POOL_SENTINEL) { page->add(POOL_SENTINEL); Return page->add(obj); return page->add(obj); }Copy the code

Reference