Skip to content

Instantly share code, notes, and snippets.

@gauravkeshre
Last active March 17, 2019 11:02
Show Gist options
  • Save gauravkeshre/583613c0db73790e0470c31cd1c3821c to your computer and use it in GitHub Desktop.
Save gauravkeshre/583613c0db73790e0470c31cd1c3821c to your computer and use it in GitHub Desktop.
ExistentialContainer Observation: Size of the reference to an existential container on a class-only protocol is 16 bytes while on normal protocol is 40 bytes.
import UIKit

/// Protocol
protocol ClassOnlyprotocol: AnyObject {
    var identifier: String {get}
    var link: String {get }
}

protocol NormalProtocol{
    var identifier: String {get }
    var link: String {get }
}

/// Implementation
class Alpha: ClassOnlyprotocol {
    
    let identifier: String
    var link: String = "link"
    init(_ id: String) {
        identifier  = id
    }
}

class Beta: NormalProtocol {
    let identifier: String
    var link: String = "link"
    
    init(_ id: String) {
        identifier  = id
    }
}


let a = Alpha("ideide")     // ■ Alpha
let b = Beta("ideide")      // ■ Beta

MemoryLayout<Alpha>.size(ofValue: a)                // ■ 8
MemoryLayout<Beta>.size(ofValue: b)                 // ■ 8 


let exa = Alpha("existential container")            // ■ Alpha
let exb = Beta("existential container")             // ■ Beta

/// size of reference
MemoryLayout<ClassOnlyprotocol>.size(ofValue: exa)  // ■ 16
MemoryLayout<NormalProtocol>.size(ofValue: exb)     // ■ 40

/// size of object
print(class_getInstanceSize(Alpha.self))        // ■ "48\n"
print(class_getInstanceSize(Beta.self))         // ■ "48\n"


func doSometingExc(_ alpha: Alpha)
{
    MemoryLayout<Alpha>.size                    // ■ 8
    MemoryLayout<Alpha>.size(ofValue: alpha)    // ■ 8
    print(alpha.identifier)                     // ■ "ideide\n"
}


func doSometingGen<A: Alpha>(_ alpha: A)
{
    MemoryLayout<A>.size                        // ■ 8
    MemoryLayout<A>.size(ofValue: alpha)        // ■ 8
    print(alpha.identifier)                     // ■ "ideide\n"
}


doSometingExc(a)
doSometingGen(a)




func readSometingExc(_ beta: Beta)
{
    MemoryLayout<Beta>.size                     // ■ 8
    MemoryLayout<Beta>.size(ofValue: beta)      // ■ 8
    print(beta.identifier)                      // ■ "ideide\n"
}


func readSometingGen<B: Beta>(_ beta: B)
{
    MemoryLayout<B>.size                        // ■ 8
    MemoryLayout<B>.size(ofValue: beta)         // ■ 8
    print(beta.identifier)                      // ■ "ideide\n"
}


readSometingExc(b)
readSometingGen(b)

/* follow: https://twitter.com/tanner0101/status/1106765161942138880 */

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment