【iOS】属性关键字

文章目录

  • 前言
  • 一、深拷贝与浅拷贝
    • 1、OC的拷贝方式有哪些
    • 2. OC对象实现的copy和mutableCopy分别为浅拷贝还是深拷贝?
    • 3. 自定义对象实现的copy和mutableCopy分别为浅拷贝还是深拷贝?
    • 4. 判断当前的深拷贝的类型?(区别是单层深拷贝还是完全深拷贝),2种深拷贝类型的相互转换?
    • 5. 代码如下所示:既然对象的mutableCopy是深拷贝,那为什么更改dataArray2,dataArray3也发生了改变?如何解决这个问题?
    • 6. 代码如下图所示:initWithArray:copyItems:YES 仅仅能进行一层深拷贝,对于第二层或者更多层的就无效了。如果想要对象每层都是深拷贝,该怎么做?
  • 二、属性关键字
    • @property
    • @synthesize
    • @dynamic
    • 原子操作
      • atomic
      • nonatomic
    • 读写权限
      • readwrite
      • readonly
    • 内存管理
      • weak
      • assign
      • assign和weak的比较
      • retain
      • strong
      • copy
      • strong与copy的区别
      • strong和copy关键字的用法
    • 1. 常用的基本类型对应Foundation数据类型?
    • 2. 定义属性的格式?(定义属性时修饰符的顺序?)
    • 3. ARC下@property的默认属性?
    • 4. 属性的读写权限关键字的含义?
    • 5. 属性的原子操作关键字的含义?
    • 6、delegate应该使用哪种关键字修饰?
    • 7、以下属性的声明有什么问题?如果一定要这么定义,如何修改成正确的呢?
    • 8、为什么@property属性用copy修饰不可变对象,而用strong修饰可变对象呢?
  • 总结


前言

先前已经在iOS的学习过程中学习了一些属性关键词的简单用法,今天这篇博客来更加深入探讨iOS中的属性关键字以及温习深拷贝与浅拷贝


一、深拷贝与浅拷贝

1、OC的拷贝方式有哪些

OC对象(集合类型和非集合类型)有2种拷贝方式,分别为浅拷贝和深拷贝。

在这里插入图片描述

  • 浅拷贝:指针拷贝,即源对象和副本对象的指针指向了同一个区域
  • 深拷贝:内容拷贝,即源对象和副本对象的指针分别指向不同的两块区域

深拷贝包括了单层深拷贝和完全深拷贝。具体后面会有讲到

  • 单层深拷贝:对于副本对象本身这一层是深拷贝,它里面的所有对象都是浅拷贝。
  • 完全深拷贝:对于副本对象本身以及它里面的所有对象都是深拷贝。

浅拷贝和深拷贝的区别:

  • 是否开辟了新的内存空间
  • 是否影响了引用计数

2. OC对象实现的copy和mutableCopy分别为浅拷贝还是深拷贝?

  • 可变对象(集合类型/非集合类型)的copy和mutableCopy都是深拷贝。
  • 不可变对象(集合类型/非集合类型)的copy是浅拷贝,mutableCopy是深拷贝。
  • copy方法返回的都是不可变对象。
    在这里插入图片描述
    具体实现过程在之前博客中已经给出:【iOS】深拷贝与浅拷贝

3. 自定义对象实现的copy和mutableCopy分别为浅拷贝还是深拷贝?

  • 自定义对象实现copy和mutableCopy都为深拷贝

因为我们的自定义对象没有copyWithZone:和mutableCopyWithZone:两个方法,需要遵守SCopying和NSMutableCopying协议来实现这两个方法,也已经在上面的链接中具体实现


4. 判断当前的深拷贝的类型?(区别是单层深拷贝还是完全深拷贝),2种深拷贝类型的相互转换?

在这里我们讨论的深拷贝的类型都是对于容器类对象来讲的,因为对于非容器类对象我们并没有单层深拷贝与完全深拷贝的区分

  • 单层深拷贝:对于副本对象本身是深拷贝,但是容器中的所有对象都是浅拷贝
  • 完全深拷贝:对于副本对象本身与其里面的所有对象都是深拷贝

实现方式

  • 单层深拷贝:
    当容器类对象中的对象是容器类对象时,使用initWithArray:copyItems:方法(第二个参数设置为YES)可以实现单层浅拷贝,因为这种拷贝只能产生一层深拷贝,对于第二层或者更多层的就无效了
  • 完全深拷贝:
    1、归档和解档来实现完全深拷贝。
    举例:dataArray3 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:dataArray2]]
    2、当容器类对象中的对象是自定义对象或不为immutable对象,使用initWithArray:copyItems:方法(第二个参数设置为YES)可以实现完全深拷贝
    这里其实也很好理解,因为我们实现自定义对象的copy时我们是需要自己实现我们的copyWithZone:和mutableCopyWithZone:两个方法,而自定义对象的拷贝始终都是深拷贝,因此通过这个方法可以实现完全深拷贝

5. 代码如下所示:既然对象的mutableCopy是深拷贝,那为什么更改dataArray2,dataArray3也发生了改变?如何解决这个问题?

在这里插入图片描述
在这里插入图片描述

问题(1). 对象的mutableCopy是深拷贝,那为什么更改dataArray2,dataArray3也发生了改变?

dataArray3 = [dataArray2 mutableCopy];  
这段代码实现的是单层深拷贝,dataArray3是dataArray2深拷贝得到的数组,但是对于array2数组中的对象array仅仅对其进行了浅拷贝,因此更改array2时array3随之改变

问题(2). 如何解决这个问题?

因为更改的对象非immutable对象,所以使用initWithArray:copyItems:方法可以实现完全深拷贝可以轻松解决这个问题

        dataArray3 = [[NSMutableArray alloc] initWithArray:dataArray2 copyItems:YES];

在这里插入图片描述

6. 代码如下图所示:initWithArray:copyItems:YES 仅仅能进行一层深拷贝,对于第二层或者更多层的就无效了。如果想要对象每层都是深拷贝,该怎么做?

在这里插入图片描述
在这里插入图片描述
使用initWithArray:copyItems:实现深拷贝仅能产生一层深拷贝,再多就没有办法实现深拷贝了,所以就需要用到解档与归档

dataArray3 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:dataArray2]];

二、属性关键字

@property

属性用于封装对象中的数据,属性的本质是 ivar + setter + getter。
可以用 @property 语法来声明属性。@property 会帮我们自动生成属性的 setter 和 getter 方法的声明

@synthesize

帮我们自动生成 setter 和 getter 方法的实现以及合成实例变量。

@dynamic

告诉编译器不用自动进行 @synthesize,你会在运行时再提供这些方法的实现,无需产生警告,但是它不会影响 @property 生成的 setter 和 getter 方法的声明。

@dynamic ivar;

以前我们需要手动对每个 @property 添加 @synthesize,而在 iOS 6 之后 LLVM 编译器引入了 property autosynthesis,即属性自动合成。换句话说,就是编译器会自动为每个 @property 添加 @synthesize。

但是这样看来似乎@synthesize就没有什么用了,其实不然:

  1. 如果我们重写了setter 和 getter 方法,则编译器就不会自动为这个 @property 添加 @synthesize,所以我们需要手动添加 @synthesize;
  2. 如果该属性是 readonly,那么只要你重写了 getter 方法,property autosynthesis 就不会执行
  3. 另外就是实现协议中要求的属性。当我们在协议中使用@property声明一个属性,在某个类中遵循这个协议,我们就必要在类中使用@synthesize来获取这个属性的成员变量,并且得到其set/get的实现函数
    在这里插入图片描述
    在这里插入图片描述

这里说到了协议,那么我们再来讨论一下Category是否能够添加使用@synthesize来合成成员变量以及实现setget方法呢?

答案是并不行,在我们的Category中我们可以声明属性,但不能声明成员变量

因为分类不是类,我们可以通过@property声明属性,但是并不能声明成员变量

Category是用来扩展现有类的功能的,而不是创建全新的类或修改类的内部实现。因此,Category不允许添加实例变量(成员变量)或使用@synthesize来合成成员变量。

以下笔者将一下为什么Category不能添加实例变量和使用@synthesize的原因:

  1. 我们的实例变量的声明我们通常需要放在类的文件中,以确保封装性,而因为分类不是类,Category只能添加方法和属性的声明,因此不允许添加实例变量,因为这会破坏类的封装性。
  2. 当我们使用@synthesize来合成成员变量时,编译器会自动生成对应的实例变量,由于Category不能添加实例变量,编译器无法为Category中的属性生成对应的实例变量,因此不允许使用@synthesize。

使用 @synthesize 关键字会合成属性的实例变量以及属性的 getter 和 setter 方法

这是我们从代码使用的层面上分析Category不能使用@synthesize的原因,接下来我们从底层结构的层面分析一下原因:

分类是在运行时去把分类中的方法添加到类的方法列表里,类的底层其实是结构体,分类可以添加属性,不能添加成员变量,因为结构体声明后不能加成员变量,而属性是结构体里的一个列表(rw:property_array_t / ro: property_list_t),就是可以加的。

而分类当中不能添加成员变量,只能通过关联对象间接实现分类有成员变量的效果,这个知识点笔者还没能理解,后面学到了加以补充

原子操作

原子操作:属性是否有原子性可以理解为线程是否安全。

  • atomic

原子性,加同步锁,默认修饰符。 使用atomic会损耗性能,也不一定保证线程安全。如果保证线程安全需要使用其他锁机制。

  • nonatomic

非原子性,不实用同步锁。 声明属性时基本设置为nonatomic。使用nonatomic能够提高访问性能。

这里笔者还没学到锁的相关知识,等学到了再加以补充

读写权限

读写权限不写时默认为 readwrite

  • readwrite

属性拥有setter方法和getter方法

  • readonly

仅有getter方法

内存管理

内存管理相关的关键词我们也可以理解为setter相关控制符,setter相关的修饰符表明setter方法应该如何实现

weak

  1. 只能修饰对象类型;
  2. ARC 下才能使用;
  3. 修饰弱引用,不增加对象引用计数,主要可以用于避免循环引用;
  4. weak 修饰的对象在被释放之后,会自动将指针置为 nil,不会产生悬垂指针;
  5. 对于视图,通常还是用在 xib 和 storyboard 上;代码中对于有必要进行 remove 的视图也可以使用 weak,这样 remove 之后会自动置为 nil。

assign

  1. 既可以修饰基本数据类型,也可以修饰对象类型;
  2. setter 方法的实现是直接赋值,一般用于基本数据类型 ;
  3. 修饰基本数据类型,如 NSInteger、BOOL、int、float 等;
  4. 修饰对象类型时,不增加其引用计数;
  5. 会产生悬垂指针(悬垂指针:assign 修饰的对象在被释放之后,指针仍然指向原对象地址,该指针变为悬垂指针。这时候如果继续通过该指针访问原对象的话,就可能导致程序崩溃)。

assign和weak的比较

相同点:对对象的引用计数没有影响,即都是弱引用。
不同点:

  1. 修饰的对象类型不同:

weak只能修饰OC对象(如UIButton、UIView等)。

assign可以修饰基本数据类型(NSInteger、NSUInteger、CGFloat、NSTimeInterval、int、float、BOOL等)和OC对象(如果用assign修饰OC对象,对象销毁时可能会产生悬垂指针,从而出现crash,不要这么做)。

注意: 使用assign修饰OC对象可能会导致程序crash,所以assign最好只用来修饰基本数据类型。

  1. 赋值的方式不同:weak复制引用,assign复制数据。
  2. 对象销毁后的状态不同:weak自动为nil,assign不变。

retain

  1. MRC 下使用,ARC 下基本使用 strong;
  2. 修饰强引用,保留新值,释放旧值,再设置新值,同时将新对象的引用计数加 1;
  3. setter 方法的实现是 release 旧值,retain 新值,用于 OC 对象类型。

我们这里详细解释一下保留新值,释放旧值,再设置新值:


strong

  1. ARC 下才能使用;
  2. 原理同 retain;
  3. 但是在修饰 block 时,strong 相当于 copy,而 retain 相当于 assign。

copy

setter 方法的实现是 release 旧值,copy 新值
一般用于 block、NSString、NSArray、NSDictionary 等类型。使用 copy 或 strong 修饰 block 其实都一样,用 copy 是为了和 MRC 下保持一致的写法;用于 NSString、NSArray、NSDictionary 是为了保证赋值后是一个不可变对象,以免遭外部修改而导致不可预期的结果。


当你使用copy特性来声明一个属性时,这意味着当设置属性时,属性会复制传入的对象,而不仅仅是保持对传入对象的引用。这通常用于确保属性拥有自己的独立副本,以避免不经意的更改。

下面是一个示例:

@property (nonatomic, copy) NSString *name;

在上面的代码中,name属性使用了copy特性。当你设置name属性时,传入的字符串会被复制,而不是保留对原始字符串的引用。这意味着如果原始字符串在后续被修改,name属性的值不会受到影响

合成的存取方法会自动处理这个行为。例如,如果你设置self.name = @“Alice”,name属性会将传入的字符串@"Alice"复制为自己的副本,而不仅仅是保存对@"Alice"的引用。


strong与copy的区别

如果属性声明中指定了copy特性,合成方法会使用类的copy方法,这里注意:属性并没有mutableCopy特性。即使是可变的实例变量,也是使用copy特性,正如方法 copyWithZone:的执行结果。所以,按照约定会生成一个对象的不可变副本

  • 相同之处:用于修饰标识拥有关系的对象
  • 不同之处:strong的赋值是多个指针指向同一个地址,而copy的复制就是每次会在内存中复制一份对象,指针指向不同的地址。
    所有对于不可变对象我们应该使用copy修饰,为确保对象中的字符串值不会无意变动,应该在设置新属性时拷贝一份

再通俗一点的理解就是用strong修饰属性并对其进行赋值时可以理解为指针拷贝,而用copy修饰时可以理解为内容拷贝

我们来给出代码的例子:

  • strong修饰
NSMutableString *otherName = [[NSMutableString alloc] initWithString:@"Jack"];
Person *person = [[Person alloc] init];
person.name = otherName;
person.age = 23;[otherName appendString:@" and Mary"];
NSLog(@"person.name = %@",person.name);
NSLog(@"%p, %p", person.name, otherName);

我们分别打印属性以及属性的地址与原始对象的地址:
在这里插入图片描述
可以看到我们的属性是可以被修改的,并且属性的地址与原始对象的地址相同,说明用strong修饰属性时,属性指向原对象的内存地址,同时使该对象引用计数加1

  • copy修饰
NSMutableString *otherName = [[NSMutableString alloc] initWithString:@"Jack"];
Person *person = [[Person alloc] init];
person.name = otherName;
person.age = 23;[otherName appendString:@" and Mary"];
NSLog(@"person.name = %@",person.name);
NSLog(@"person.name = %@",otherName);
NSLog(@"%p, %p", person.name, otherName);

当我们属性修饰改为copy时,打印出的结果如下图所示:
在这里插入图片描述

可以看到我们属性指向的地址与原始对象的地址不同,并且我们的属性指向的内存空间的数据并未被修改,但是原对象的数据被修改了,说明用copy进行修饰属性对其进行赋值时会创建一块新的内存空间,属性指向新创建的内存空间,本质其实就是内容拷贝(深拷贝)

strong和copy关键字的用法

@property属性用copy修饰不可变对象,用strong修饰可变对象。

1. 常用的基本类型对应Foundation数据类型?

在声明一个属性时,尽量使用Foundation框架的数据类型,使代码的数据类型更统一。
基本类型和Foundation数据类型的对应关系如下:

  • int -> NSInteger
  • unsigned -> NSUInteger
  • float -> CGFloat
  • 动画时间 -> NSTimeInterval

2. 定义属性的格式?(定义属性时修饰符的顺序?)

推荐按照下面的格式来定义属性

@property (nonatomic, readwrite, copy) NSString *name;

属性的修饰符应该按照上面的顺序排列:原子操作、读写权限、内存管理

3. ARC下@property的默认属性?

对于基本数据类型:atomic、readwrite、assign
对于普通的Objective-C对象:atomic、readwrite、strong

4. 属性的读写权限关键字的含义?

读写权限

readwrite:可读可写,默认修饰符。会自动生成getter和setter
readonly:只读。只会生成getter而不生成setter

5. 属性的原子操作关键字的含义?

原子操作:属性是否有原子性可以理解为线程是否安全。

atomic:原子性,加同步锁,默认修饰符。
使用atomic会损耗性能,也不一定保证线程安全。如果保证线程安全需要使用其他锁机制。

nonatomic:非原子性,不实用同步锁。
声明属性时基本设置为nonatomic。使用nonatomic能够提高访问性能。

这里设计到了一些锁的知识,还没有学到,后面学到再进行补充

6、delegate应该使用哪种关键字修饰?

MRC时期:使用assign,这样不会造成循环引用,但是需要手动释放。
ARC时期:最好使用weak,如果使⽤了assign需要⼿动释放。如果没写释放逻辑,当⻚面销毁的时候,很可能出现delegate对象无效,导致程序crash。

7、以下属性的声明有什么问题?如果一定要这么定义,如何修改成正确的呢?

@property (nonatomic, copy) NSMutableArray *mutableArray;

如果我们对属性进行增删改等操作时,程序会崩溃,因为当我们对属性进行赋值时,copy复制的是一个不可变的NSArray对象

具体分析:不应该使用copy关键字来修饰可变对象。
copy修饰的属性会在内存里拷贝一份对象,即两个指针指向不同的内存地址。
Foundation框架提供的可变对象类型都已实现了NSCopying协议,所以使用copy方法返回的都是不可变对象
本题中,用copy关键字修饰了可变数组,那么当对该属性赋值时会得到一个NSArray类型的不可变数组。
因为是NSArray类型,即是不可变的数组类型,所以如果对属性进⾏了可变数组的增删改功能都会导致crash。

所以正确写法如下
@property (nonatomic, strong) NSMutableArray *mutableArray;


如果一定要用copy,我们需要重写setter方法,因为对当属性用copy修饰进行赋值时,会自动调用setter方法执行copyWithZone:方法,返回的是不可变对象,所以我们需要对待吗进行如下修改:

// .h文件
@property (nonatomic, copy) NSMutableArray *mutableArray;// .m文件
// 重写setter⽅法 使_mutableArray变为可变的copy
- (void)setMutableArray:(NSMutableArray *)mutableArray {_mutableArray = [mutableArray mutableCopy]; 
}- (void )viewDidLoad { [super viewDidLoad];NSMutableArray *array = [NSMutableArray arrayWithObjects:@1, @2, nil]; self.mutableArray = array;[self.mutableArray removeObjectAtIndex:0]; NSLog(@"self.mutableArray:%@", self.mutableArray);
}输出:
self.mutableArray:( 2
)

8、为什么@property属性用copy修饰不可变对象,而用strong修饰可变对象呢?

  • 用copy修饰不可变对象:

copy修饰的属性会在内存里拷贝一份对象,即两个指针指向不同的内存地址。
Foundation框架提供的对象类型都已实现了NSCopying协议,所以使用copy方法返回的都是不可变对象。
即使源对象是可变对象(实现属性所用的对象是mutable),copy后的对象也不会随之改变
确保了对象不会无意间被改动。

  • 用strong修饰可变对象:

strong修饰的属性是对属性进行了强引用,即两个指针会指向同一个内存地址。
如果源对象可变,strong修饰的对象也会随之改变。

总结

属性关键字的细节还有很多很多,后面学到更多的知识会加以补充

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/127172.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于SSM的农产品推广应用网站

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用Vue技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…

Mac电脑其他文件占用超过一大半的内存如何清理?

mac的存储空间时不时会提示内存已满,查看内存占用比例最大的居然是「其他文件」,「其他文件」是Mac无法识别的格式文件或应用插件扩展等等...如果你想要给Mac做一次彻底的磁盘空间清理,首当其冲可先对「其他文件」下手,那么我们该…

华为云中对象存储服务软件开发工具包(OBS SDK) C语言介绍

华为云的OBS介绍:摘自华为云官网:https://support.huaweicloud.com/obs/index.html 华为云的对象存储服务(Object Storage Service,OBS)是一个基于对象的海量存储服务,为客户提供海量、安全、高可靠、低成本的数据存储能力。 …

RocketMQ_高级特性_事务消息

Apache RocketMQ在4.3.0版中已经支持分布式事务消息,这里RocketMQ采用了2PC的思想来实现了提交事务消息,同时增加一个补偿逻辑来处理二阶段超时或者失败的消息,如下图所示。 事务消息发送步骤如下: 生产者将半事务消息发送至消息队…

基于jeecg-boot的flowable流程自定义业务退回撤回或驳回到发起人后的再次流程提交

更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码: https://gitee.com/nbacheng/nbcio-boot 前端代码:https://gitee.com/nbacheng/nbcio-vue.git 在线演示(包括H5) : http://122.227.135.243:9888 主要…

SpringMVC实现增删改查(CRUD)--从头到尾全面详细讲解

一&#xff0c;实现CRUD前准备工作 1.1 pom.xml依赖的配置 创建Model项目并导入相关pom.xml依赖 <properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><m…

Agisoft Metashape相机标定笔记

Lens Calibration(镜头标定) 使用Metashape进行自动相机标定是可能的。Metashape使用LCD显示屏作为标定目标&#xff08;可选&#xff1a;使用打印的棋盘格图案&#xff0c;但需保证它是平坦的且单元格是正方形&#xff09;。 相机标定步骤支持全相机标定矩阵的估计&#xff…

以可视化方式解释 Go 并发 - 通道

在并发编程中&#xff0c;许多编程语言采用共享内存/状态模型。然而&#xff0c;Go 通过实现 通信顺序进程 (CSP) 区别于众多语言。在 CSP 中&#xff0c;一个程序由并行的进程组成&#xff0c;这些进程不共享状态&#xff0c;而是使用通道进行通信和同步它们的操作。因此&…

Linux编辑器 VI VIM

vim 命令模式 插入模式 ex模式 \ 命令模式 /查找关键字后&#xff0c;按n键在找到的结果之前来换的切换、 EX模式

Ubuntu编译运行socket.io

本篇文章记录一下自己在ubuntu上编译运行socket.io的过程&#xff0c;客户端选用的是socket.io的c的库&#xff0c;编译起来倒不难&#xff0c;但是说到运行的话&#xff0c;对我来说确实是花了点功夫。毕竟程序要能运行起来才能更方便地去熟悉代码&#xff0c;因此今天我就记录…

常见排序算法

排序简介常见排序算法插入排序直接插入排序希尔排序 选择排序选择排序堆排序 交换排序冒泡排序快速排序hoare版挖坑法前后指针法非递归实现快排优化 归并排序非递归实现归并排序海量数据排序问题 基数排序&#xff08;不用比较就能够排序&#xff09;桶排序计数排序&#xff08…

Zoom正式发布类ChatGPT产品—AI Companion

9月6日&#xff0c;全球视频会议领导者Zoom在官网宣布&#xff0c;正式发布生成式AI助手——AI Companion。 AI Companion提供了与ChatGPT类似的功能&#xff0c;包括根据文本对话起草各种内容&#xff0c;自动生成会议摘要&#xff0c;自动回答会议相关问题等&#xff0c;以帮…

Windows下安装配置Nginx

nginx安装 官网下载地址 https://nginx.org/en/download.html 推荐使用稳定版本 截止时间2023年9月5日稳定版本为 1.24.0 百度网盘 链接&#xff1a;https://pan.baidu.com/s/1cXm-jN2fMzKdVMRhbG72Fg 提取码&#xff1a;9hcq 下载完成以后,得到nginx压缩包; 双击启动nginx.…

3D目标检测数据集 KITTI(标签格式解析、点云转图像、点云转BEV)

本文介绍在3D目标检测中&#xff0c;理解和使用KITTI 数据集&#xff0c;包括KITTI 的基本情况、下载数据集、标签格式解析、点云转图像、点云转BEV。 目录 1、KITTI数据集中3D框可视化的效果 2、先看个视频&#xff0c;了解KITTI 的基本情况 3、来到KITTI官网&#xff0c;下…

电脑提示“系统找不到指定的文件”怎么办?

“系统找不到指定的文件”对于Windows用户来说是一个很常见的错误&#xff0c;尤其是Win10用户&#xff0c;经常会遇到Win10提示找不到指定文件。在此错误后面有时还会出现错误代码&#xff1a;0x80070002&#xff0c;但是&#xff0c;故障类型或代码在不同的操作系统规范上是不…

文本生成模型如何解码

文章目录 解码方法Greedy SearchBeam SearchsamplingTemperature Samplingtop-k samplingTop-p (nucleus) samplingContrastive search 总结相关资源 语言模型如何对于一个给定输入生成相应的输出呢&#xff1f;答案是使用解码策略(decoding strategy)。这里对现有的解码策略做…

用python实现基本数据结构【02/4】

*说明 如果需要用到这些知识却没有掌握&#xff0c;则会让人感到沮丧&#xff0c;也可能导致面试被拒。无论是花几天时间“突击”&#xff0c;还是利用零碎的时间持续学习&#xff0c;在数据结构上下点功夫都是值得的。那么Python 中有哪些数据结构呢&#xff1f;列表、字典、集…

【白话机器学习系列】白话梯度下降

白话梯度下降 梯度下降是机器学习中最常见的优化算法之一。理解它的基本实现是理解所有基于它构建的高级优化算法的基础。 文章目录 优化算法一维梯度下降均方误差梯度下降什么是均方误差单权重双权重三权重三个以上权重 矩阵求导结论 优化算法 在机器学习中&#xff0c;优化是…

ChatGPT实战与私有化大模型落地

文章目录 大模型现状baseline底座选择数据构造迁移方法评价思考 领域大模型训练技巧Tokenizer分布式深度学习数据并行管道并行向量并行分布式框架——Megatron-LM分布式深度学习框架——Colossal-AI分布式深度学习框架——DeepSpeedP-tuning 微调 资源消耗模型推理加速模型推理…

Python批处理(一)提取txt中数据存入excel

Python批处理&#xff08;一&#xff09;提取txt中数据存入excel 问题描述 现从冠层分析软件中保存了叶面积指数分析的结果&#xff0c;然而软件保存格式为txt&#xff0c;且在不同的文件夹中&#xff0c;每个文件夹的txt文件数量不固定&#xff0c;但是txt文件格式固定。现需…