swift class的缺省基类(SwiftObject)与内存模型
Hard Constraints on Resilience
The root of a class hierarchy must remain stable, at pain of invalidating the metaclass hierarchy. Note that a Swift class without an explicit base class is implicitly rooted in the SwiftObject Objective-C class.
https://github.com/apple/swift/blob/master/docs/ABI/TypeLayout.rst
//===----------------------------------------------------------------------===// |
|
// |
|
// This implements the Objective-C root class that provides basic `id`- |
|
// compatibility and `NSObject` protocol conformance for pure Swift classes. |
|
// |
|
//===----------------------------------------------------------------------===// |
SWIFT_RUNTIME_EXPORT @interface SwiftObject<NSObject> { |
|||||
@private |
|||||
Class isa; |
|||||
SWIFT_HEAPOBJECT_NON_OBJC_MEMBERS; |
|||||
}
….. |
https://github.com/apple/swift/blob/f4db1dd7a4abba2685247e1a7415d4fcb91f640d/stdlib/public/runtime/SwiftObject.h
// The members of the HeapObject header that are not shared by a |
|
// standard Objective-C instance |
|
#define SWIFT_HEAPOBJECT_NON_OBJC_MEMBERS \ |
|
InlineRefCounts refCounts |
oc端的函数可以使用oc调用约定进行调用;
swift本地端的函数可以使用swift调用约定进行调用;
https://github.com/apple/swift/blob/master/stdlib/public/SwiftShims/HeapObject.h
接下来是 SWIFT_HEAPOBJECT_NON_OBJC_MEMBERS,这是一个宏定义,展开后即:
RefCounts<InlineRefCountBits> refCounts;
这是一个相当重要东西,引用计数、弱引用、unowned 引用都与它有关,同时它也是 Swift 对象(文中后续的 Swift 对象均指引用类型,即 class 的实例)中较为复杂的一个结构。
http://www.manongjc.com/article/64837.html
Swift是苹果公司最新推出的编程语言,据很多人说,是用来”代替“Objective-C。但是没有确切的证据。我花了一些时间对Swift二进制和运行环境实施逆向工程技术,然后我对Swift有些少许的发现。目前为止,结论就是:Swift是没有消息机制的Objective-C。
对象
信不信由你,Swift中的对象就是Objective-C的对象。在Mach-O二进制文件中,__objc_classlist包含每个二进制文件中类的数据。其结构如下所示:
struct objc_class {
uint64_t isa;
uint64_t superclass;
uint64_t cache;
uint64_t vtable;
uint64_t data;
};
https://www.oschina.net/translate/inside-swift
class Human {
//8 type or isa
//retainCount
var age: Int?//16
var name: String?//16
var nicknames: [String] = [String]()
//返回指向 Human 实例头部的指针
func headPointerOfClass() -> UnsafeMutablePointer<Int8> {
let opaquePointer = Unmanaged.passUnretained(self as AnyObject).toOpaque()
let mutableTypedPointer = opaquePointer.bindMemory(to: Int8.self, capacity: MemoryLayout<Human>.stride)
return UnsafeMutablePointer<Int8>(mutableTypedPointer)
}
}
MemoryLayout<Human>.size //8
let human = Human()
let arrFormJson = ["goudan","zhaosi", "wangwu"]
//拿到指向 human 堆内存的 void * 指针
let humanRawPtr = UnsafeMutableRawPointer(human.headPointerOfClass())
//nicknames 数组在内存中偏移 48byte 的位置(8+8+16+16)
let humanNickNamesPtr = humanRawPtr.advanced(by: 48).assumingMemoryBound(to: Array<String>.self)
print(human.nicknames)
//[]
humanNickNamesPtr.initialize(to: arrFormJson)
print(human.nicknames)
human.nicknames //["goudan","zhaosi", "wangwu"]
let retainCount = humanRawPtr.advanced(by: 8).assumingMemoryBound(to: Int8.self)
print(retainCount.pointee)
参考文献:
https://www.cnblogs.com/doudouyoutang/p/9760603.html
https://www.oschina.net/translate/inside-swift
swift class的缺省基类(SwiftObject)与内存模型的更多相关文章
- cocos2d-x 的两大基类
cocos2d-x 有两个重要的基类,一个管理引用计数的 Ref,别一个则定义许多基本属性的 Node. 在 cocos2d-x 中的基本概念 说到 create 函数的时候提到 cocos2d-x ...
- 派生类地址比基类地址少4(子类与基类指针强行转换的时候,值居然会发生变化,不知道Delphi BCB是不是也这样) good
大家对虚表并不陌生,都知道每个含有虚函数的类对象都有1个虚指针,但是在现实使用中,却总是因为这而调试半天,才发现原来是虚指针惹的祸.我这几天在调试代码时候也中招了,我的问题是这样的,如下图,CTree ...
- NO.6: 为多态基类声明virtual析构函数
注意:polymorphic base class 应该具有虚析构函数,如果class带有任何virtual函数,也应具有虚析构函数 class不具备polymorphic属性则不应该声明virtua ...
- C++ 基类指针和子类指针相互赋值
首先,给出基类animal和子类fish [cpp] view plaincopy //======================================================== ...
- 派生类地址比基类地址少4(CDerived对象的起始地址存放的是虚表指针vptr,也就是子类的第一项内容。接下来的是基类的成员变量,接下来再是自身的成员变量)
大家对虚表并不陌生,都知道每个含有虚函数的类对象都有1个虚指针,但是在现实使用中,却总是因为这而调试半天,才发现原来是虚指针惹的祸.我这几天在调试代码时候也中招了,我的问题是这样的,如下图,CTree ...
- [Swift实际操作]九、完整实例-(5)创建BaseViewController作为控制器的基类
本文将给项目中的所有视图控制器,创建一份基类.该基类用来定义一些共用的属性和方法. 首先在用来放置视图控制器类的文件夹上点击鼠标右键,打开右键 菜单. 选择[New File]创建文件选项. 在弹出的 ...
- Swift中文教程(五)--对象和类
原文:Swift中文教程(五)--对象和类 Class 类 在Swift中可以用class关键字后跟类名创建一个类.在类里,一个属性的声明写法同一个常量或变量的声明写法一样,除非这个属性是在类的上下文 ...
- C++ - 虚基类、虚函数与纯虚函数
虚基类 在说明其作用前先看一段代码 class A{public: int iValue;}; class B:public A{public: void bPrintf(){ ...
- C++ (P160—)多继承 二义性 虚基类 “向上转型”
1 多继承中,必须给每个基类指定一种派生类型,如果缺省,相应的基类则取私有派生类型,而不是和前一个基类取相同的派生类型 2 一个类的保护成员只能被本类的成员函数或者它的派生类成员函数访问 3 由于c+ ...
随机推荐
- 偏流角(Draft Angle)在等距螺旋中的作用
劳动改变人,思维改变世界.我们可以接着聊螺旋线了. 在飞行程序设计中,偏流角(Draft Angle简写为DA)通常指得是受侧风影响航向偏移的最大角度.用速度向量来表示时,是图1中的三角形关系: 图1 ...
- Spark SQL结构化数据处理
Spark SQL是Spark框架的重要组成部分, 主要用于结构化数据处理和对Spark数据执行类SQL的查询. DataFrame是一个分布式的,按照命名列的形式组织的数据集合. 一张SQL数据表可 ...
- Docker入门之一Docker在Window下安装
最近这几年,各个大公司都在打造自己的云平台,什么阿里云,华为云,腾讯云等等云,以及各种的微服务架构,其实在这当中Docker容器技术算是一个很重要的角色. 一.下载 在下载之前首先检查一下自己的电脑是 ...
- c# Datatable导出Excel
using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using System; using System.Collections.Generic; ...
- Redis管道
介绍 Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务.客户端请求会遵循以下步骤:客户端向服务端发送一个查询请求,并监听Socket返回,通常是以阻塞模式,等待服务端响应并将结果返 ...
- 使用Nexus2.x为Maven3.x搭建私服构件仓库
前言 在笔者的前一篇博文<Use Maven3.x>中,笔者详细的讲解了如何通过使用Maven3.x来构建及管理你的项目.其中笔者提到过些关于私服的概念,但却没有明确的对私服做出详细的阐述 ...
- Pseudocode MD5 CODE
//Note: All variables are unsigned 32 bit and wrap modulo 2^32 when calculating var int[64] s, K //s ...
- Stackoverflow 珠玑:C#封装重试指定次数的功能
最近写的一个 .NET Core 爬虫里用到了需要多次重试的功能,本着无脑输出的精神,google 了一下,还真给我找到了: public static T Retry<T, TExceptio ...
- Linux 学习笔记之超详细基础linux命令 Part 12
Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 11---------------- ...
- EventBus结合rxjava2和retrofit2网络获取
依赖: compile 'com.squareup.retrofit2:converter-gson:2.3.0'compile 'com.squareup.retrofit2:retrofit:2. ...