iOS基础问题整理

atomic和nonatomic区别,以及作用?

atomicnonatomic的主要区别在于系统自动生成的getter/setter方法实现不同:

  • atomic:系统自动生成的getter/setter方法会进行加锁操作
  • nonatomic:系统自动生成的getter/setter方法不会进行加锁操作

atomic的局限性:不是线程安全的

  • 系统生成的getter/setter方法会进行加锁操作,但这个锁仅仅保证了getter和setter方法内部赋值/读取操作的原子性
  • 由于加锁的缘故,在多个线程同时访问同一个属性的getter/setter时,会按顺序执行操作
  • 重要澄清atomic完全不能防止对象在getter/setter被调用时被其他线程释放。它不提供任何对象生命周期的保障。要解决线程安全问题,需要依靠ARC、信号量等线程安全机制

weak 和 assign 的不同点

  • weak策略在属性所指的对象遭到摧毁时,系统会将weak修饰的属性对象的指针指向nil,在OC中给nil发送消息是安全的
  • 如果使用assign策略,在属性所指的对象遭到摧毁时,属性对象指针仍指向原来的对象地址,产生野指针,此时给此对象发送消息容易造成程序崩溃
  • assign可以用于修饰非OC对象(基本数据类型),而weak必须用于OC对象

ARC 下,不显式指定任何属性关键字时,默认的关键字都有哪些?

  • 基本数据类型:atomic, readwrite, assign
  • 普通的 OC 对象:atomic, readwrite, strong

怎么用 copy 关键字?

  • NSString、NSArray、NSDictionary等经常使用copy关键字,是因为它们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary。为确保对象中的属性值不会无意间变动,应该在设置新属性值时拷贝一份,保护其封装性
  • block也经常使用copy关键字。在MRC下,方法内部的block默认在栈区,使用copy可以把它放到堆区
  • 更新说明 :在ARC环境下,编译器会自动地将作为属性被strongcopy修饰的block从栈拷贝到堆。因此,在ARC下使用strongcopy对于block的效果相同,但Apple的文档和编码惯例仍然推荐使用copy

说一下OC的反射机制

  • OC的反射机制主要基于OC的动态语言特性
  • 系统Foundation框架提供了一些方法反射的API
  • 我们可以通过这些API执行将字符串转为SEL等操作
  • 由于OC语言的动态性,这些操作都发生在运行时

什么是僵尸对象?

  • 已经被销毁的对象(不能再使用的对象),内存已经被回收的对象

野指针

  • 指向僵尸对象(不可用内存/已经释放的内存地址)的指针

数组copy后里面的元素会复制一份新的吗

  • 不会,数组的浅拷贝(copy)只复制数组容器本身,数组里面存储的是之前对象的地址引用,不会创建新的对象实例

OC中的NSInteger 和int 有什么区别

  • 在32位操作系统时,NSInteger 等价于 int(32位)
  • 在64位操作系统时,NSInteger 等价于 long(64位)

NSMutableDictionary 中使用setValueForKey 和 setObjectForKey有什么区别?

  • 根据官方文档说明:一般情况下,给NSMutableDictionary发送setValue仍然是调用setObject方法,如果参数value为nil,则会调用removeObject移除这个键值对
  • setObjectForKey是NSMutableDictionary特有的,value不能为nil,否则会崩溃
  • setValueForKey是KVC的方法,key必须是字符串类型,而setObject的key可以是任意类型

面向对象的三大特性:

  1. 封装 隐藏对象的属性和实现细节,仅对外提供公共访问方式,将变化隔离,便于使用,提高复用性和安全性

  2. 继承 提高代码复用性;建立类之间的关系;子类可以拥有父类的所有成员变量和方法;继承是多态的前提

  3. 多态 父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,提高程序的拓展性

什么是多态?

  • 核心定义:多态在面向对象语言中指同一个接口有多种不同的实现方式。在OC中,多态是不同对象对同一消息的不同响应方式
  • 子类通过重写父类的方法来改变同一方法的实现,体现多态性
  • 实现方式:通过父类类型的指针指向子类的对象,在运行时根据对象的实际类型调用正确的方法实现
  • 多态就是某一类事物的多种形态,继承是多态的前提

什么是分类?

  • 分类:在不修改原有类代码的情况下,为类添加方法
  • Category可以为类扩展方法,或者通过运行时关联属性。Category底层结构是一个结构体,内部存储结构体的名字、所属类的信息、对象方法和类方法列表、协议、属性信息
  • 通过Runtime加载某个类的所有Category数据
  • 把所有Category的方法、属性、协议数据合并到一个大数组中,后面参与编译的Category数据会在数组的前面
  • 重要说明:运行时将分类的方法合并到主类中,后编译的分类方法会出现在方法列表前部。当消息发送时,运行时会按顺序查找方法,因此分类中的方法会覆盖主类中的同名方法

如何实现多继承?

重要说明:OC不支持像C++那样的直接多继承,但可以通过以下方式实现类似效果:

  1. 消息转发机制 :通过forwardingTargetForSelector:forwardInvocation:将消息转发给其他对象
  2. 协议:定义多个协议,实现"多接口"而非真正的多继承
  3. 组合模式:持有多个其他类的实例,通过方法转发来复用功能
  4. 类别:只能为已有类添加方法,无法实现真正的多继承

为什么说OC是一门动态语言?

  • 动态语言:指程序在运行时可以改变其结构,新的函数可以被引进,已有的函数可以被删除等结构上的变化
  • 动态类型语言:类型的检查是在运行时做的

OC的动态特性体现在三个方面:

  • 动态类型:最终判定该类的实例类型是在运行期间
  • 动态绑定:在运行时确定调用的方法
  • 动态加载:在运行期间加载需要的资源或可执行代码

动态绑定

  • 动态绑定将调用方法的确定推迟到运行时。OC可以先跳过编译,到运行的时候才动态地添加函数调用,在运行时才决定要调用什么方法,需要传什么参数进去
  • 在编译时,方法的调用并不和代码绑定在一起,只有在消息发送出来之后,才确定被调用的代码。通过动态类型和动态绑定技术,实现真正的运行时多态

动态语言和静态语言

  • 动态类型语言:数据类型的检查是在运行时做的。用动态类型语言编程时,不用给变量指定数据类型,该语言会在第一次赋值给变量时,在内部记录数据类型
  • 静态类型语言:数据类型的检查是在运行前(如编译阶段)做的

关于二维数组的说明

OC中没有原生的二维数组语法,但可以通过NSArrayNSMutableArray中嵌套另一个NSArray来模拟和实现二维数组的功能,这在实践中是普遍和有效的做法

相关推荐
椒盐螺丝钉17 小时前
Vue Router应用:组件跳转
前端·javascript·vue.js
顾安r17 小时前
11.20 开源APP
服务器·前端·javascript·python·css3
敲敲了个代码18 小时前
CSS 像素≠物理像素:0.5px 效果的核心密码是什么?
前端·javascript·css·学习·面试
少云清18 小时前
【软件测试】5_基础知识 _CSS
前端·css·tensorflow
倔强青铜三18 小时前
AI编程革命:React + shadcn/ui 将终结前端框架之战
前端·人工智能·ai编程
天外飞雨道沧桑18 小时前
前端开发 Cursor MCP 提效工具配置
前端·vscode·ai编程·开发工具·cursor
朱哈哈O_o19 小时前
前端通用包的作用——jquery篇
前端
葡萄城技术团队19 小时前
纯前端驱动:在线 Excel 工具的技术革新与实践方案
前端·excel
芳草萋萋鹦鹉洲哦19 小时前
【vue】调用同页面其他组件方法几种新思路
前端·javascript·vue.js
巴啦啦臭魔仙19 小时前
uniapp scroll-view自定义下拉刷新的坑
前端·javascript·uni-app