Swift中,Struct在栈区,Class对象分配在堆区?

2020-05-12  本文已影响0人  righr

学习Swift时,有各种Struct和Class的比较,不少博客,指出Struct速度快,分配在栈区,而Class分配在堆上。初听觉得,有道理。但是有一个疑问,对象是局部变量,class对象还需要底层调用底层api分配堆,是否多余了?所以写了个demo,汇编层面,一探究竟。

class 类如下:


class Person {
    
    var age: Int? = 21;
    var age1: Int? = 1;
    var age2: Int? = 2;
    var age3: Int? = 1;
    var age4: Int? = 2;
    var age5: Int? = 2;
    var age6: Int? = 2;
    
    func begin(path pathStr: String) ->Bool {
        
        let manager = FileManager.default
        let rs = manager.fileExists(atPath: pathStr)
        
        var i = 50;
        for j in 0..<100 {
            i = i + j
        }
        
        let manager2 = FileManager.default
        let rs2 = manager2.fileExists(atPath: pathStr)
        if( rs && rs2 && age! > 10 && i > 230) {
            return true;
        }
        
        return false;
    }
}

ViewController中调用代码

class ViewController: UIViewController {

     override func viewDidLoad() {
        super.viewDidLoad()
        
        let p: Person = Person()
        p.begin(path: "asdf");
        
    }
}

设置为Release模式,在 super.viewDidLoad() 代码处断点。运行,断点后,从Debug->Debug Work Flow -> Always Show Disassembly,切换到汇编模式。

1.jpg

swift_initStackObject 看名字,就知道是分配栈区的,如果还不信,可以进入这个方法看下,其实汇编也没多少,没有堆申请,只是简单的栈空间返回。在断点处打印了,返回的x0寄存器和sp栈底寄存器。一摸一样。其实这个是在Rlease模式是这样的,如果是Debug模式。是会分配在栈区的。

2.jpg

class 对象在方法中,以局部变量存在时,其实就是分配在栈区。避免堆申请,系统调用。

当class 对象以属性,存在于Controller中时,我们也看看吧。代码如下:


class ViewController: UIViewController {
    
    let p: Person = Person()
    
     override func viewDidLoad() {
        super.viewDidLoad()
        
        p.begin(path: "asdf");
        
    }
}

Person 内下断点,查看变量是如何分配的。


3.jpg

swift_allocObject 就是alloc对象的。分配完成后,返回在x0中,然后调用SwiftTableDemo.Person.init() -> SwiftTableDemo.Person 完成初始化对象。

结论: class 对象以属性存在时,需要在堆中存在的,当是局部变量时,是分配在stack中。其实Struct 也类似,局部变量存在时,存在栈区,属性存在时,存在堆区。

上一篇下一篇

猜你喜欢

热点阅读