iOS底层-对象里都有什么

2023-05-16

前言

上篇文章说了iOS中alloc方法是怎么创建对象的,以及对象的本质是结构体。接下来继续探究对象的内存分布,以及对象的isa是个什么样的结构体,存储了哪些信息。

对象内存分布

已知系统给对象分配内存是16字节对齐的;

@interface FFGoods : NSObject

@property (nonatomic ,copy) NSString *goodsName;  // 0-8
@property (nonatomic ,copy) NSString *type; // 9-15
@property (nonatomic ,assign) int goodsId; // 16-19
@property (nonatomic ,assign) double weight;  // 24-31
@property (nonatomic ,assign) short number; // 32-33
// 33经过16字节对齐后 -> 48

@end

那么以上实例应该是48字节:

image-20220420095646500

如果加一个类方法和实例方法,这个对象占用的内存大小会不会发生变化呢?

image-20220420095952777

说明没有影响。对于实例对象,内存分配是由isa + 成员变量的值,这是之前的结论。

既然成员变量的值存储在对象里面,会不会受到属性的书写顺序影响?

打印goods实例的内存地址前,先解释一下将会出现的lldb指令:

p 能够知道引用类型,po只能打印值;

p/x 表示按照16字节打印,还有p/o 是8字节 , p/t 是2字节, p/f 是浮点数

x/6gx: 第一个x代表打印对象的内存地址,/后面是参数;4g代表连续4个8字节的地址,最后个x代表16进制;

image-20220420102902582

goodsName为什么没有紧跟在isa后面?

isa指针后面的8字节:0x0000007b00000038,尝试分为 0x0000007b0x00000038 2段打印:

image-20220420103058035

发现4字节的int和2字节的short会放在一个8字节的内存空间里。因为iOS会自动重排属性的顺序,达到内存优化。

再增加一个char属性(int + short + char < 8字节),

@property (nonatomic ,assign) char abc;

发现还是排在同个8字节空间里:因为对象内部是8字节对齐的。

image-20220420103639944

再看一个例子:


#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface FFTestObject : NSObject
{
@public
    int count;
    NSObject *subObject1;
    NSObject *subObject2;
}
@end

@interface FFTestSubObject : FFTestObject
{
@public
    int subCount;
}
@end

NS_ASSUME_NONNULL_END

打印:

image-20220420113929595

然后我调整父类 int 属性的顺序,再运行看到 subObject 实际占用变成32。这说明成员变量的顺序还是会对内存造成微小影响的

image-20220420114530398

父类在内存中是一块连续的内存空间,子类无法修改和插入。也就是iOS对子类的成员变量,不会跟其父类混合重排在一起。图中int放在尾部时,子类可以跟在父类后面,填补空白的内存。

平时开发时不用特别在意,相差几个字节对内存影响太小。

至于iOS的自动重排,还得从位域说起。

位域

C语言允许在一个结构体中以位为单位来指定其成员所占内存长度,这种以位为单位的成员称为“位段”或称**“位域”( bit field)** 。

定义2个结构体:

C可以在定义结构体的同时定义结构体变量,不过OC在.h文件中定义需要使用typedef修饰。
struct Student{
// …
} student1,student2;

struct FFStructA {
    char a;
    char b;
    char c;
    char d;
}structA;

struct FFStructB {
    char a : 1;
    char b : 1;
    char c : 1;
    char d : 1;
}structB;

打印内存大小,发现structB为什么只占1个字节?

image-20220420134716472

这就是位域的作用,a:1 表明只需要1个位域(二进制的1个比特位),位域的特点是不能超过数据类型的最大长度

当前字节剩余位域不够用的时候,会直接从下个字节开始存放。修改位域,再打印发现内存占用变成2字节:

image-20220420141447070

不过位域节省的空间实在有限,只有系统级别才会用到。对于开发者不需要节约,而是不要去浪费。

联合体

新建一个结构体和联合体:

struct FFGoods {
    char *name;
    int number;
    double height;
}goodsStruct;

union UnionStudent {
    char *name;
    int number;
    double height;
}goodsUnion;

在没赋值前,打印出联合体与结构体一样都是初始值;赋值一个属性后就不一样了,其他属性会是个乱七八糟的值;

image-20220420152704551

union就是属性共用一块内存空间,系统会分配一块足够大的内存空间;成员变量就相当于开辟了几种去访问这一整块内存的途径。

上图为什么会出现乱七八糟的值?一开始的时候赋值字符,那么其他成员的数据类型指针去读取字符串的时候自然是错误的

联合体的作用也是能节省一定的内存空间,所占内存取决于最大成员变量,例子中就是double类型占8字节。

同时还得满足最大基本数据类型的整数倍:

union UnionStudent {
    char *name;
    int number;
    double height; // 8字节
    char a[9]; // 1 * 9 = 9 字节;但是要满足最大基本数据类型(这里是double)的整数倍
}goodsUnion;

这跟结构体内存对齐道理一样:

image-20220420153604682

与结构体的区别:

结构体是共存,内存开辟比较粗放,只要写了内存变量就会去开辟内存空间;

联合体是互斥的,省内存空间;

对象的isa

那么联合体在objc底层是怎么使用的?

来到objc源码的_class_createInstanceFromZone方法,上回只说到calloc,接着看后面的方法。代码中实例化的时候加一个断点,看看会发生什么。

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSLog(@"Hello World!");
    
        FFPhone *phone = [FFPhone alloc]; // 这行加断点
        logPhone(phone);
    }
    return 0;
}

目前为止,还只是id类型,跟自己创建的类还没有什么关系。通过calloc开辟的内存空间如何与类产生关联?

image-20220420162854760

运行到下一个断点,po一下,看到已经是我们的类了。实际上就是通过前面的initisa函数进行关联的。

image-20220420162930499

注意initInstanceIsa这个分支,代码里最终还会调用initisa:

inline void 
objc_object::initInstanceIsa(Class cls, bool hasCxxDtor)
{
    ASSERT(!cls->instancesRequireRawIsa());
    ASSERT(hasCxxDtor == cls->hasCxxDtor());

    initIsa(cls, true, hasCxxDtor);
}

来到 initIsa 看看具体做什么:

image-20220420163437623

Tips:简单提一下,第328行 isTaggedPointer 是指针优化

第355行,extra_rc代表引用计数的值;通过alloc方法创建出来的对象,引用计数就是1,并且存在于isa指针里。

可以看到isa_t 查看发现,破案了!iOS的isa指针结构居然是联合体。

image-20220420164301937

这里对代码加一些注释:有2个构造器和3个数据成员。通过94行得出,当有几东西只能同时存在一个的时候,确实适合用联合体;


#include "isa.h"

union isa_t {
    // 2个构造器
    isa_t() { } 
    isa_t(uintptr_t value) : bits(value) { }
        // 数据成员1,64位内存占用
    uintptr_t bits;
// 数据成员2,Class类型指针
private:
    // Accessing the class requires custom ptrauth operations, so
    // force clients to go through setClass/getClass by making this
    // private.
    Class cls;

public:
#if defined(ISA_BITFIELD)
    // 数据成员3
    struct {
        ISA_BITFIELD;  // defined in isa.h
    };
        // 是否被释放了?引用计数+散列表里的计数
    bool isDeallocating() {
        return extra_rc == 0 && has_sidetable_rc == 0;
    }
    // 释放对象
    void setDeallocating() {
        extra_rc = 0;
        has_sidetable_rc = 0;
    }
#endif

    void setClass(Class cls, objc_object *obj);
    Class getClass(bool authenticated);
    Class getDecodedClass(bool authenticated);
};

既然是联合体,那么3个数据成员只会同时存在一个。看到这个判断条件:

#if defined(ISA_BITFIELD)

如果没定义ISA_BITFIELD,那么isa_t就是Class类型的结构体指针;既然给了64位内存,只存放Class指针肯定是不划算的。那么iOS根据情况切换成其他数据成员。

如果有定义ISA_BITFIELD,就变成另一种结构体,ISA_BITFIELD本身还代表这些结构体成员有哪些:

image-20220420170102496

看到 elif __x86_64__ ,原来这个数据成员还区分架构的。我的是intel芯片的mac系统,架构是__x86_64__

以下是arm64模拟器和真机:(__has_feature: 是否支持指针的身份验证;A12芯片后引出的;)


# if __arm64__
// ARM64 simulators have a larger address space, so use the ARM64e
// scheme even when simulators build for ARM64-not-e.
#   if __has_feature(ptrauth_calls) || TARGET_OS_SIMULATOR
#     define ISA_MASK        0x007ffffffffffff8ULL
#     define ISA_MAGIC_MASK  0x0000000000000001ULL
#     define ISA_MAGIC_VALUE 0x0000000000000001ULL
#     define ISA_HAS_CXX_DTOR_BIT 0
#     define ISA_BITFIELD                                                      \
        uintptr_t nonpointer        : 1;                                       \
        uintptr_t has_assoc         : 1;                                       \
        uintptr_t weakly_referenced : 1;                                       \
        uintptr_t shiftcls_and_sig  : 52;                                      \
        uintptr_t has_sidetable_rc  : 1;                                       \
        uintptr_t extra_rc          : 8
#     define RC_ONE   (1ULL<<56)
#     define RC_HALF  (1ULL<<7)
#   else
#     define ISA_MASK        0x0000000ffffffff8ULL
#     define ISA_MAGIC_MASK  0x000003f000000001ULL
#     define ISA_MAGIC_VALUE 0x000001a000000001ULL
#     define ISA_HAS_CXX_DTOR_BIT 1
#     define ISA_BITFIELD                                                      \
        uintptr_t nonpointer        : 1;                                       \
        uintptr_t has_assoc         : 1;                                       \
        uintptr_t has_cxx_dtor      : 1;                                       \
        uintptr_t shiftcls          : 33; /*MACH_VM_MAX_ADDRESS 0x1000000000*/ \
        uintptr_t magic             : 6;                                       \
        uintptr_t weakly_referenced : 1;                                       \
        uintptr_t unused            : 1;                                       \
        uintptr_t has_sidetable_rc  : 1;                                       \
        uintptr_t extra_rc          : 19
#     define RC_ONE   (1ULL<<45)
#     define RC_HALF  (1ULL<<18)
#   endif

nonPointerIsa

注意到isa结构体成员中的uintptr_t nonpointer : 1,当nonpointer=1的时候,代表开启指针优化,这时候的isa指针也叫做nonPointerIsa指针。关于指针的内容今后会单独讲一篇,这里稍微提一下。

单独整理一下不同架构的isa结构和里面指针的含义。

arm64 (模拟器):

uintptr_t nonpointer        : 1;                                   
uintptr_t has_assoc         : 1;                                    
uintptr_t weakly_referenced : 1;                                   
uintptr_t shiftcls_and_sig  : 52;                                 
uintptr_t has_sidetable_rc  : 1;                            
uintptr_t extra_rc          : 8

arm64 (真机):

uintptr_t nonpointer        : 1;
uintptr_t has_assoc         : 1;
uintptr_t has_cxx_dtor      : 1;
uintptr_t shiftcls          : 33;
uintptr_t magic             : 6;
uintptr_t weakly_referenced : 1;
uintptr_t unused            : 1;
uintptr_t has_sidetable_rc  : 1;
uintptr_t extra_rc          : 19

x86_64:

uintptr_t nonpointer        : 1;
uintptr_t has_assoc         : 1;
uintptr_t has_cxx_dtor      : 1;
uintptr_t shiftcls          : 44;
uintptr_t magic             : 6;
uintptr_t weakly_referenced : 1;
uintptr_t unused            : 1;
uintptr_t has_sidetable_rc  : 1;
uintptr_t extra_rc          : 8

指针含义:

指针含义
nonpointer是否对 isa 指针开启指针优化。0:纯isa指针,1:不止是类对象地址,isa还包含了类信息、对象的引用计数等
has_assoc是否有关联对象
has_cxx_dtor该对象是否有 C++ 或者 Objc 的析构器。如果有析构函数,则需要做析构逻辑,如果没有,则可以更快的释放对象
shiftcls存储类指针的值。开启指针优化的情况下,来存储类指针,在不同架构中位数不同。
magic用于调试器判断当前对象是真的对象,还是没有初始化的内存空间
weakly_referenced对象是否被指向或者曾经指向一个 ARC 的弱变量, 没有弱引用的对象可以更快释放
deallocating标志对象是否正在释放内存
has_sidetable_rc是否有使用 sidetable 散列表来存储引用计数,通常是引用计数extra_rc存满了
extra_rc表示该对象的引用计数值

回到刚才的demo;打印对象内存地址后怎么通过地址来获取内部这些指针呢?

获取isa里的指针

例如__x86_64__架构ISA_BITFIELD的这个uintptr_t shiftcls : 44;指针,要单独取出这中间的44位,就意味着将左右位数据都变成0。通过位运算,左移右移能达到效果。这里就是右移3位到最右边,左移20(右3+左17)位回到最左边,再右移17位移回原来的位置。

为什么前三个在右边?内存地址右边是低位,属性又是从低位开始存。

lldb通过 p/x address >> 3 << 20 >> 17;得到后的地址就是该实例对象的类对象地址空间。验证如下:

image-20220420173230366

接下来尝试获取extra_rc,因为在高8位,直接右移 64-8 = 56 位就行了;前面会补0 ;并且为了测试再加一个指针引用:

image-20220420200042686

结论:引用计数的上限取决于cpu架构。并且次数上限 c o u n t = 2 n − 1 count = 2^n - 1 count=2n1,n为位数。

我就要问了,要是存储就是超过了怎么办?借位,存到散列表里;并用has_sidetable_rc标识;

以上位移操作获取类对象地址不用这么麻烦,系统有 ISA_MASK 掩码帮你完成了;

这与之前介绍的对象内部8字节对齐时,WORD_MASK是一样的:

static inline uint32_t word_align(uint32_t x) {
    return (x + WORD_MASK) & ~WORD_MASK;
}

这是ISA_MASK的定义:define ISA_MASK 0x00007ffffffffff8ULL ,直接进行与运算就能得到类对象地址。

image-20220420232116076

用计算器查看这个掩码的位:本质是就是你需要保留的位都置1,其余0。与运算后0位都是0。

image-20220420232602001

结尾的ULL = unsigned long long

总结

影响对象内存的因素

isa通过位域的形式,将对象相关的信息存储起来在8字节里面。所以影响对象内存的只有成员变量(属性会自动生成带下划线的成员变量)。

对象的内存分布

在对象的内部是以8字节进行对⻬的。苹果会自动重成员变量的顺序,将占用不足 8 字节的成员挨在一起,凑满 8 字节,以达到优化内存的目的。

联合体(union)

联合体的成员变量就相当于为这块内存空间开辟了几个访问途径,他们共享这一块内存。

联合体的大小规则:

  • 必须能容纳联合体中最大的成员变量
  • 必须是数据成员中最大的基本数据类型大小的整数倍

联合体和结构体的区别 :

  • 结构体中所有变量是“共存”的,而联合体(union)中是各变量是“互斥”的。
  • 一个完整,一个灵活。

位域

  • 位域的宽度不能超过声明的数据类型的最大⻓度。比如int占4个字节也就是32位,那:号后面的数字就不
    能超过32。
  • 如一个字节所剩空间不够存放另一位域时,则会从下一单元起存放
    该位域。
  • 位域能够节省一定的内存空间。

nonPointerIsa

  • nonPointerIsa是内存优化的一种手段。isa是一个Class类型的结构体指针,占8个字节也就是64位。然而存储地址根本不需要这么大的内存空间。而且每个对象都有个isa指针,这样就浪费了内存。所以iOS就把和对象相关的信息,存在了这块内存空间里面。这种isa指针就叫nonPointerIsa

  • 通过isa的位运算得到类对象。借助系统提供的掩码ISA_MASK就能轻松得到,使用时注意区分架构。同时还可以通过平移得到其他对象信息。

对象的结构体关系图

image-20220506135016434

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS底层-对象里都有什么 的相关文章

  • 通信协议 - ARINC615A加卸载协议

    概述 ARINC615A加卸载端系统由加载端软件和目标端软件组成 xff0c 通过加载端软件和目标端软件的通信共同完成端系统设备的数据加卸载功能 加载端软件运行于大容量设备中 xff0c 被加载端即目标端软件运行于AFDX交换机内和其他端系
  • 我用C语言玩对象,封装相似算法的策略模式

    概述 在策略模式 xff08 Strategy Pattern xff09 中 xff0c 一个类的行为或其算法可以在运行时更改 这种类型的设计模式属于行为型模式 在策略模式中 xff0c 我们创建表示各种策略的对象和一个行为随着策略对象改
  • 浅谈linux - 库文件制作与使用

    概述 本质上来说 xff0c 库文件就是可执行代码的二进制形式 xff0c 可以被操作系统载入内存中执行 Linux操作系统支持的函数库分为静态库和动态库 xff0c 动态库又称共享库 Linux系统有几个重要的目录存放相应的函数库 xff
  • 浅谈linux - vs code搭建运行调试环境

    概述 在Linux开发过程中 xff0c 用不惯vim的用户往往会选择vs code软件或者source insight软件编写相关的源代码 xff0c 由于vs code对linux系统的支持及界面的美观 xff0c 所以小编往往会选择使
  • 浅谈linux - samba实现linux与windows文件共享

    概述 Samba是一个能让Linux系统应用Microsoft网络通讯协议的软件 xff0c 而SMB是Server Message Block的缩写 xff0c 即为服务器消息块 xff0c SMB主要是作为Microsoft的网络通讯协
  • mysql的update、delete、和insert into时表别名用法

    mysql数据库update delete 和insert into表的时候 xff0c 如果要使用表别名 xff0c 必须按照规范写法来写 xff1a insert xff1a 简写 xff1a insert into t a a a i
  • 浅谈linux - RT Linux解决方案

    概述 RT Linux Real Time Linux 亦称作实时 Linux xff0c 是 Linux 中的一种硬实时操作系统 xff0c 它最早由美国墨西哥理工学院的 V Yodaiken 开发 产品资料提供的 Linux RT 内核
  • 浅谈linux - 线程的基本应用

    概述 线程 xff08 英语 xff1a thread xff09 是操作系统能够进行运算调度的最小单位 它被包含在进程之中 xff0c 是进程中的实际运作单位 注意 线程和进程之间的区别 1 线程是执行的基本单位 xff1b 进程是资源分
  • 浅谈linux - mutex锁应用

    概述 互斥锁是专门用于处理线程之间互斥关系的一种方式 xff0c 它有两种状态 xff1a 上锁状态 解锁状态 如果互斥锁处于上锁状态 xff0c 那么再上锁就会阻塞到这把锁解开为止 xff0c 才能上锁 解锁状态下依然可以解锁 xff0c
  • 浅谈linux - cond条件变量应用

    概述 条件变量不是一个把锁 xff0c 它实质上一个类似信号的东西 xff0c 与锁相互配合使用 xff0c 因为锁所能达到的功能就只有加锁和解锁 xff0c 并不能实现线程之间的一些关联 xff0c 于是条件变量就出现了 xff0c 与锁
  • 设计UI - Adobe xd画板及参考线

    画板 新建画板 a 使用预设画板大小或创建自定义画板 操作步骤 xff1a 打开xd软件 xff0c 点击需要建立的画板模版 xff0c 没有则选择自定义大小 b 使用画板工具创建其它画板 操作步骤 xff1a 选中画板工具 xff0c 选
  • activity的启动模式与newIntent()

    很多知识当我们用到的时候 xff0c 才发觉有多好用 今天需要完成一个功能 xff0c 创建一个悬浮窗 xff0c 点击悬浮窗上按钮 xff0c 加载到一个包含webView 的activity xff0c 为了避免activity重复创建
  • 基于DOCKER安装华为自研数据库高斯(GAUSS)

    华为数据库裸机安装比较困难 xff0c 我们可以采用docker的安装方式 xff0c 自己学习和测试使用 安装环境 1 xff09 centos 7 9 2 xff09 docker版本 opengauss 注意 xff0c 我们在安装此
  • MariaDB 中文乱码问题解决

    编辑文件 vim etc my cnf d server cnf 在 mysqld 下面添加两行 init connect 61 39 SET NAMES utf8 39 character set server 61 utf8 重启Mar
  • 【Linux】安装kali遇到的一些细节

    前言 本文省略安装教程 xff0c 如有安装教程需求 xff0c 请自行查阅 博主安装的版本为 xff1a kali 2023 1 amd 64 一 gdm3默认管理器 情景 其它系统基础配置进度完成后 xff0c 大部分安装的人 xff0
  • Windows 2016 修改密码时提示密码不符合规则

    一 现象描述 在修改服务器密码时 xff0c 遇到如下情况 xff1a 提示密码不满足密码策略要求 二 处理方法 在电脑服务器管理中找到 工具 单击 本地安全策略 进入策略管理 在本地安全策略中找到帐户安全策略 xff0c 单击进入 帐户策
  • MATLAB即将跌出TOP 20,TIOBE 4月编程语言排行榜出炉

    CSDN 编者按 一月一次的编程语言排行榜出炉 xff01 责编 张红月 出品 CSDN xff08 ID xff1a CSDNnews xff09 在TIOBE发布的4月编程语言排行榜中 xff0c 知名数学算法分析语言MATLAB即将跌
  • python3 爬虫实战案例 (抓取淘宝信息)(淘宝加了搜索必须登录的验证,此方法所到的结果都是0)

    需求 xff1a 对比足球 xff0c 篮球 xff0c 乒乓球 xff0c 羽毛球 xff0c 网球 xff0c 相关物品的销售量保存到excle中 和抓取淘宝关键字相关信息的销售量 xff0c 这和之前抓取csdn网站浏览量取不同 xf
  • android studio中Gradle 编译需要重点注意gradle,wrapper,build tools之间的版本对应关系

    Android Studio 2 3 的平台已经已经是相对稳定的发布版 xff0c 新的功能不断推出 xff0c 包括对NDK 的完美支持 它看起来有一些重大的改变也正在等待合适的孵化时机 xff0c 如 xff1a 新的 Gradle 构
  • VNC Viewer 设置屏幕分辨率-解决屏幕分辨率问题

    先介绍一款好用的连接工具介绍一个 VNC连接工具 xff1a http fwqglgj iis7 net cp vnc tscc IIs7服务器管理工具可以批量连接并管理VNC服务器 作为服务器集成管理器 xff0c 它最优秀的功能就是批量

随机推荐

  • LAMP环境简单搭建

    一 简介 LAMP 是Linux Apache MySQL PHP的简写 xff0c 其实就是把Apache MySQL以及PHP安装在Linux系统上 xff0c 组成一个环境来运行php的脚本语言 Apache是最常用的WEB服务软件
  • 转身不带走一丝云彩--我的2014

    时间或许就是这样不管你愿意不愿意都会毫不犹疑的向前 xff0c 逼你成长 2014年得到了很多也失去了很多 xff0c 我对未来还是有诸多憧憬的 谨以此文献给过去的时光 xff0c 也希望对后来人能有所帮助 改变篇 相比于2013年 xff
  • 一年装三次Arch Linux,每次都有新收获

    只要跟随优秀的教程 xff0c 装机过程so easy archlinux 双系统真机安装演示 哔哩哔哩 bilibili Archlinux系统安装 xff0c 配置 xff0c 游戏 黑客驰HackerChi 哔哩哔哩 bilibili
  • Linux系统中PS1命令详解

    本帖主要针对经常使用Linux命令行且对命令行界面美观和可阅读性有一定要求的同学 xff0c 主要讲解如何通过修改PS1命令定义命令行的显示以及提供一条可直接复用的PS1命令 原文链接 简介 xff1a PS1命令是linux系统中的一个全
  • firewalld

    一 firewalld 介绍 firewalld 防火墙 xff0c 其实就是一个隔离工具 xff1a 工作于主机或者网络的边缘 xff0c 对于进出本主机或者网络的报文根据事先定义好的网络规则做匹配检测 xff0c 对于能够被规则所匹配的
  • yum升级CURL到最新版本的方法,非常好用

    首先 xff0c 先为你的服务器获取最新匹配的源 xff1a http mirror city fan org ftp contrib yum repo 安装新版libcurl的yum源 rpm ivh http mirror city f
  • 百度笔试题2018

    题外话 首先我要吐槽一下 xff0c csdn简直是在作死啊 xff0c 复制博文底下的那个引用太恶心了 xff0c 我复制自己的博客 xff0c 还有引用 xff0c 啥玩意啊 所以我决定换地方了 xff0c 以后github xff08
  • 你见过的最全面的Python重点知识总结!

    这是一份来自于 SegmentFault 上的开发者 64 二十一 总结的 Python 重点 由于总结了太多的东西 xff0c 所以篇幅有点长 xff0c 这也是作者 34 缝缝补补 34 总结了好久的东西 xff0c 强烈建议收藏再慢慢
  • 程序员经典语录

    程序员编程语录 1 一个好的程序员是那种过单行线马路都要往两边看的人 xff08 Doug Linder xff09 2 程序有问题时不要担心 如果所有东西都没问题 xff0c 你就失业了 xff08 软件工程的Mosher定律 xff09
  • 使用fastboot命令刷机流程详解

    一 Fastboot是什么 1 1 首先介绍Recovery模式 卡刷 在系统进行定制时 xff0c 编译系统会编译出一份ZIP的压缩包 xff0c 里面是一些系统分区镜像 xff0c 提供给客户进行手动升级 恢复系统 需要提前将压缩包内置
  • 【谷歌插件】谷歌插件制作

    文章目录 谷歌浏览器插件制作教程实现步骤成功示例问题未封装的扩展程序并非来自 Chrome 网上应用商店 谷歌浏览器插件制作 教程 教程1 xff1a https blog csdn net github 35631540 article
  • 一个刚毕业大学生的四个月苦逼程序员经历

    先来一个自我介绍 大学时排名老三 就暂且叫老三吧 xff0c 毕业于河南的一个还算可以的二本院校 xff0c 专业 地球信息科学与技术 首先介绍一下我的专业 xff0c 听着名字很高大上 xff0c 其实 xff0c 我们都叫他四不像专业
  • JS中的require、import、default、export

    刚开始学的时候经常弄混总结一下 xff1a 懒人 xff1a 1 require xff08 导入 xff09 是Commonjs的规范与module exports xff08 导出 xff09 搭配使用 2 import xff08 导
  • Ubuntu安装python3

    sudo apt get install python3 安装python3 xff0c 安装完之后系统默认还是python2 xff0c 要删除python link文件 sudo rm rf usr bin python 然后建立新连接
  • ubuntu安装shutter出现E:无法修正错误

    使用Ubuntu16 04安装shutter时出现如下错误 通过换源可以解决
  • Ubuntu不能访问Windows分区

    将Windows的快速启动关闭即可解决次问题 在电脑中安装了双系统 xff0c 但有时候在Ubuntu中访问Windows分区会出现如下错误 xff1a 以前出现过这种错误 xff0c 是因为windows系统没有完全关闭 xff0c 当时
  • Ubuntu和Windows双系统时间不对的解决办法

    在使用一系统再切换到另一个系统之后 xff0c 系统时间好像是停留在上次关闭该系统的时间 在网上的解决办法通常是 xff1a sudo gedit etc default rcS xff0c 将UTC 61 yes改成UTC 61 no 但
  • Ubuntu出现依赖关系问题 - 仍未被配置问题

    安装软件包时候出现如下错误 xff1a 但这并不是依赖问题 xff0c 使用sudo apt get f install 无法解决 其实问题是因为这六个软件包没有被完全安装或卸载 在安装其他软件的时候会出现 xff1a 就是指这六个软件 使
  • 熬夜总结!最全的Pycharm常用快捷键大全!

    版权声明 xff1a 本文为博主原创文章 xff0c 遵循 CC 4 0 BY SA 版权协议 xff0c 转载请附上原文出处链接和本声明 本文链接 xff1a https blog csdn net momoda118 article d
  • iOS底层-对象里都有什么

    前言 上篇文章说了iOS中alloc方法是怎么创建对象的 xff0c 以及对象的本质是结构体 接下来继续探究对象的内存分布 xff0c 以及对象的isa是个什么样的结构体 xff0c 存储了哪些信息 对象内存分布 已知系统给对象分配内存是1