iOS原理之内存管理AutoRelease底层实现

//
//  MemoryManagemnet-AutoreleasePool-ViewController.swift
//  iOS底层
//
//  Created by yanqunchao on 2019/5/23.
//  Copyright © 2019 yanqunchao. All rights reserved.
//

import UIKit


class MemoryManagemnet_AutoreleasePool_ViewController: UIViewController {
 
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .white
        
        atautoreleasepool {
            for _ in 0..<20 {
               let obj = NSObject().autorelease()
            }
            atautoreleasepool {
                for _ in 0..<30 {
                   let obj = NSObject().autorelease()
                }
                objc_autoreleasePoolPrint()
            }
        }
    }
} 
//
//  NSObject+Autorelease.swift
//  iOS底层
//
//  Created by yanqunchao on 2019/5/24.
//  Copyright © 2019 yanqunchao. All rights reserved.
//

import Foundation

let maxPoolPageCount = 10
var poolPageArr:[AutoreleasePoolPage] = []
typealias ReleaseFunc = ()->()

class AutoreleasePoolPage {
    var objAddrArr:[NSObject?] = []
}
class __AtAutoreleasePool {
    var atautoreleasepoolobj:NSObject?
    
    init(boundary:NSObject?) {
        atautoreleasepoolobj =  objc_autoreleasePoplPush(boundary: boundary!)
    }
    deinit {
        objc_autoreleasePoplPop()
    }
    func objc_autoreleasePoplPush(boundary:NSObject?) ->NSObject?{
        return boundary
    }
    func objc_autoreleasePoplPop(){
        atautoreleasepoolobj = nil
    }
}

class PoolBoundary:NSObject {
}

extension NSObject {
    func autorelease() ->NSObject{
        if (poolPageArr.last?.objAddrArr.count)! >= maxPoolPageCount {
            let page = AutoreleasePoolPage()
            poolPageArr.append(page)
        }
        poolPageArr.last!.objAddrArr.append(self)
        return self
    }
    
    func atautoreleasepool(releaseFunc:ReleaseFunc){
        let boundaryAddr = autoreleaseBegin {
            releaseFunc()
        }
        autoreleaseEnd(boundaryAddr:boundaryAddr)
    }
    
    func autoreleaseBegin(releaseFunc:ReleaseFunc) ->NSObject?{
        let POOL_BOUNDARY = PoolBoundary()
        let releasePool = __AtAutoreleasePool(boundary: POOL_BOUNDARY)
        var lastPoolPage:AutoreleasePoolPage?
        if poolPageArr.count == 0 {  //如果存储page的数组为空,就创建一个page,填充进去
            let page = AutoreleasePoolPage()
            poolPageArr.append(page)
        }
        lastPoolPage = poolPageArr.last
        if lastPoolPage!.objAddrArr.count >= maxPoolPageCount {  //如果存储容量最大容量,要创建新的poolPage
            let page = AutoreleasePoolPage()
            poolPageArr.append(page)
            lastPoolPage = poolPageArr.last!
        }
        lastPoolPage!.objAddrArr.append(releasePool.atautoreleasepoolobj!)
        releaseFunc()
        return releasePool.atautoreleasepoolobj!
    }
    
    func autoreleaseEnd(boundaryAddr:NSObject?){
        //倒序pageArr
        for i in stride(from: poolPageArr.count - 1, through: 0, by: -1) {
            let poolPage = poolPageArr[i]
            for j in stride(from: poolPage.objAddrArr.count - 1, through: 0, by: -1) {
                //倒序objAddrArr
                let objAddr = poolPage.objAddrArr[j]
                poolPage.objAddrArr.remove(at: j)
                if poolPage.objAddrArr.count == 0 {
                    poolPageArr.remove(at: i)
                }
                if objAddr == boundaryAddr{
                    return
                }
            }
        } 
    }
     //打印autoreleasePool的内容信息
    func objc_autoreleasePoolPrint(){
        if poolPageArr.count == 0 {
           print("........PAGE EMPTY........ ")
        }else{
            for (i,page) in poolPageArr.enumerated() {
                
                let hot = i == poolPageArr.count - 1 ? "hot" : "cold"
                
                if page.objAddrArr.count == maxPoolPageCount {
                    print("...........  PAGE (full) (\(hot))")
                }else{
                    print("...........  PAGE (\(hot))")
                }
                
                for objAddr in page.objAddrArr {
                    if objAddr!.className == "PoolBoundary" {
                        print("###########  POOL \(objAddr!)")
                    }else{
                        print("  \(objAddr!)")
                    }
                }
            }
        }
    }
}

你可能感兴趣的:(iOS原理之内存管理AutoRelease底层实现)