objective c 语言特点
-
面向对象
-
动态性:可以在运行时动态地修改类和对象的结构,这种特性使得它非常灵活。
-
消息传递机制:在 Objective-C 中,对象之间的通信是通过消息传递代替函数调用。
-
扩展性:Objective-C 支持类别和协议,这使得可以在不修改原始类的情况下,为现有的类添加新的方法和行为,提高了代码的可维护性和可扩展性。
-
内存管理:引入了自动引用计数(ARC)来简化内存管理的工作。
-
丰富的框架:Objective-C 提供了丰富的框架,包括 Cocoa 和 Cocoa Touch,用于开发 macOS 和 iOS 应用程序。这些框架提供了大量的现成功能,加速了应用程序的开发过程。
-
与 C 和 C++ 的兼容性:Objective-C 是在 C 语言基础上发展起来的,因此可以直接调用 C 语言的函数和库。此外,Objective-C++ 允许在 Objective-C 代码中混合使用 C++ 代码。
内存管理
- 自动引用计数ARC是一个由编译器自动插入内存管理代码的技术,它负责在编译时自动为对象保留和释放内存。
- 在ARC下,开发者不需要手动调用
retain
、release
和autorelease
。编译器会根据代码的结构自动插入这些内存管理的方法,确保对象在不再被使用时会被释放。开发者只需要关心对象的生命周期,例如声明一个强引用或者弱引用。
retain
:手动增加引用计数release
:手动减少引用计数- 自动释放池:是一种用来管理对象生命周期的机制。当你使用一个方法创建一个对象,但不想在当前方法内负责释放该对象时,你可以将该对象放入自动释放池中。当自动释放池被释放时,它会向池中的所有对象发送一条release消息,从而释放这些对象。
- 强引用:对象会在有强引用指向它的时候被保留,当没有强引用指向它时,对象会被释放。
- 弱引用:对象不会被强制保留,当没有强引用指向它时,对象会被释放。它不会增加对象的引用计数。弱引用通常用于避免循环引用的问题。
- 循环引用:指两个或多个对象之间相互(强)引用,导致它们之间的引用计数无法降为零,从而导致内存泄漏。
BUG
内存泄漏
内存泄漏指的是在程序中动态分配的内存在不再需要时没有被释放。
ARC(自动引用计数)可以大大减少内存泄漏的可能性
野指针
指向已经释放的内存的指针。
isa指针
isa
- OC对象都继承自NSObject,而NSObject又包含一个isa,所以结构体内有isa即可判定为OC对象;
- isa为对象的第一个成员,它的地址即为对象的起始地址;
oc对象分类
- instance对象(实例对象)
- class对象(类对象)
- meta-class对象(元类对象)
instance对象(实例对象)在内存中存储的信息
- isa指针
- 其他成员变量
class对象(类对象)在内存中存储的信息
每个类在内存中有且只有一个class对象
- isa指针
- superclass指针
- 类的属性信息(@property)
- 类的对象方法信息(instance method)
- 类的协议信息(protocol)
- 类的成员变量信息(ivar)
meta-class对象(元类对象)在内存中存储的信息
- 每个类在内存中有且只有一个meta-class对象
- meta-class对象和class对象的内存结构是一样的,但是用途不一样
- isa指针
- superclass指针
- 类的类方法信息(class method)
总结
- 实例对象(instance)的isa指向类对象(class)
- 类对象(class)的isa指向元类对象(meta-class)
- class的superclass指向父类的class,如果没有父类,superclass指针为nil
- meta-class的superclass指向父类的meta-class,基类的meta-class的superclass指向基类的class
- instance调用对象方法的轨迹:isa找到class,方法不存在,就通过superclass找父类
- class调用类方法的轨迹:isa找meta-class,方法不存在,就通过superclass找父类
代理模式
- 是一种常用的设计模式,用于在对象之间传递数据或者通知事件发生。代理模式通过协议实现,允许一个对象代表另一个对象处理某些事务。
- 定义协议
- 委托对象:
@interface MyDelegateClass : NSObject <MyDelegate>
- 设置代理:
@property (nonatomic, weak) id<MyDelegate> delegate;
- 使用代理
块
- 块(Blocks)是一种允许你封装一段代码并在需要的时候执行的语法结构。它们类似于匿名函数或闭包,可以在任何地方定义、传递和执行。
- 块可以捕获其作用域内的变量,这种特性使得块非常强大,可以用于实现回调、异步操作、枚举等各种场景。
runloop
- 运行循环是一个事件处理和线程管理的机制,允许应用程序响应用户输入、定时器、网络请求和其他事件。RunLoop使得应用程序能够持续运行并响应事件,而不会消耗大量的CPU资源。
- RunLoop管理了程序的事件处理循环,允许程序等待事件的发生并响应这些事件。当没有事件需要处理时,RunLoop可以将应用程序置于休眠状态,从而节省CPU资源。当有事件需要处理时,RunLoop会被唤醒,并执行相应的事件处理代码。