Ios 减少发布100万+;弹出VC时的对象

Ios 减少发布100万+;弹出VC时的对象,ios,memory-management,automatic-ref-counting,dealloc,Ios,Memory Management,Automatic Ref Counting,Dealloc,当前的iOS应用程序需要从服务器上下载超过一百万个对象,并且出于某些目的,我们将其保存在一个阵列中。当用户完成此功能后,应用程序需要一段时间才能返回上一个屏幕(约15秒),因为100万个对象正在被释放。我们可以从仪器中看到,在这段时间(15秒)内,计数从100万变为0。是否有任何方法可以加快释放阵列中的这些1 mn对象的速度?与其尝试更快地释放这些对象,我建议您以更慢的速度释放它们 把这些东西都放在别的地方。创建一些singleton[ObjectsManager sharedInstance]

当前的iOS应用程序需要从服务器上下载超过一百万个对象,并且出于某些目的,我们将其保存在一个阵列中。当用户完成此功能后,应用程序需要一段时间才能返回上一个屏幕(约15秒),因为100万个对象正在被释放。我们可以从仪器中看到,在这段时间(15秒)内,计数从100万变为0。是否有任何方法可以加快释放阵列中的这些1 mn对象的速度?

与其尝试更快地释放这些对象,我建议您以更慢的速度释放它们

  • 把这些东西都放在别的地方。创建一些singleton
    [ObjectsManager sharedInstance]
    ,它将负责下载所有这些对象并将其保存在一些
    NSMutableArray
  • 在其他VCs中随时使用这些对象
  • 完成后,告诉您的
    [[ObjectsManager sharedInstance]RemoveAllDownloadedObject]
    ,这将缓慢地
    NSMutableArray中删除所有对象
  • 不要写
    [myArray removeAllObjects]
    ,而是一部分一部分地写--使用
    NSOperation
    GCD
    每秒删除20000个对象

  • 在iphone6s上,我在大约1.5秒的时间内释放了约600 MB的100万个实例(选择了昂贵的
    UIView
    )。当使用普通类(~50MB)进行测试时,需要约0.2秒。尽管如此,如果您可以将数据保存在struct中,您将接近于零。我相信,你正在其他地方浪费时间

    import UIKit
    
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
    
        var window: UIWindow?
    
        class C: UIView {
            static var c = 0
            deinit { C.c -= 1 }
            init() { C.c += 1; super.init(frame: CGRect.zero) }
            required init?(coder aDecoder: NSCoder) { fatalError() }
        }
    
        func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    
            var a: [C]? = []
            for i in 0..<1_000_000 {
                a!.insert(C(), atIndex: i)
            }
    
            print(C.c) // We have 1_000_000 allocations.
    
            let t1 = CFAbsoluteTimeGetCurrent()
            a = nil
            let t2 = CFAbsoluteTimeGetCurrent()
    
            print(t2 - t1) // 1 milion instances of ~600 MB freed in ~1.5 seconds.
            print(C.c) // ARC works!
    
            return true
        }
    }
    
    导入UIKit
    @UIApplicationMain
    类AppDelegate:UIResponder、UIApplicationLegate{
    变量窗口:UIWindow?
    C类:UIView{
    静态变量c=0
    脱硝{C.C-=1}
    init(){C.C+=1;super.init(frame:CGRect.zero)}
    必需的初始化?(编码器aDecoder:NSCoder){fatalError()}
    }
    func应用程序(应用程序:UIApplication,didFinishLaunchingWithOptions启动选项:[NSObject:AnyObject]?)->Bool{
    变量a:[C]?=[]
    
    对于0中的i.问题是
    堆碎片化
    。用ie ObjC/C/C++等语言释放连续内存块速度很快。相比之下,释放碎片化内存速度很慢。这很难测试,因为分配和释放模式经常会影响您看到的碎片量。举个例子可能会有所帮助。

    许多分配器使用大小混合的链表箱进行分配。当你在循环中分配一百万个链表时,你可能会有很多连续的内存块,当在循环中释放时,这些内存块会利用缓存等,看起来很快。当你在生产中测试它时,速度就不那么快了

    避免它的唯一方法是避免堆碎片,这意味着

  • 分配包含N个对象的块,并一次性取消分配每个块
  • 理想情况下,为N个对象的整个集合分配一个连续内存区域,并在一次调用中取消分配

  • 我希望这些对象中的每一个都只有几个字节。你在真正的设备上测试过吗?是的,它已经在设备上测试过了。对象数组本身大约需要15 MB的内存。你没有提供任何代码或信息,因此很难跟踪正在进行的操作。你有标签自动引用计数,所以我可以m假设您使用的是arc。返回上一个屏幕时您是否正在执行代码?dealloc方法中是否有代码?分配了多少次?释放15MB内存不应花费15秒,除非您为每个对象分配了一次。您是否可以为这些对象预分配空间?您是否尝试过
    @autorelease{}
    pool.iOS会自动管理对象的解除分配。一旦VC不再使用,这将自动删除已创建对象的引用。当前的方法是在ViewWillEnglishe方法中将数组设置为nil。在仪器运行时,可以观察到设置为nil不会立即强制解除分配。虽然控制转到下一行,但解除分配继续并行进行,数组的大小变得越来越小。您确定
    viewwilldefine
    是执行如此昂贵的操作的好地方吗?您可能想再次显示/显示它,此时您的数据将丢失。除非您有我对它进行了良好的设计,我会在
    deinit
    中将它隐式释放。解除分配不立即的原因可能是存在对象的其他所有者(另一个数组、单元格等)。还要区分解除初始化和解除分配。一旦强制解除初始化(ARC发现对象的引用计数为零),你很好,让系统做dealloc(这不会立即发生).而且…这里我强烈建议考虑
    struct
    s。好吧,在视图中设置它将消失是最早开始解除分配的地方。这没有问题,因为VC会弹出,底层VC会显示,在这段时间内,解除分配会继续发生。您不想过早地进行,但smoo第三,如果你没有理由在
    视图中这样做,那么就不要这样做。在考虑@OlDor的解决方案时也要小心。当你需要在完成“缓慢删除”之前插入新对象时,你可能会遇到赛车问题。设计这样的模式有点棘手。“每秒删除20000个对象”我的设计很有缺陷。很有意思。让我试一个例子,看看这对我们是否有效。我们将尝试这个选项。为什么要一部分一部分地删除它?