Objective-C基础教程
import语句
和 C ⼀样,Objective-C 也使⽤头⽂件来包含结构体、符号常量和函数原型等元素的声明。C 中使⽤ #include 语句,在 Objective-C 中虽然有也可以使⽤ #include,但是我们不会这么做,⽽是使⽤ #import 语句。#import 是 Xcode 编译器提供的,可保证头⽂件只被包含⼀次,⽆论此命令在该⽂件总出现了多少次。
在 C 中,通常使⽤基于 #ifdef 命令的⽅案来避免⼀个⽂件包含另⼀个⽂件⽽后者⼜包含前者的情况。
⽽在 Objective-C 中,使⽤ #import 命令来实现这个功能。
布尔(Boolean)类型
布尔类型指的是可以存储真值和假值的变量类型。C 的布尔数据类型 bool 具有 true 和 faluse 两个值,Objective-C 的 BOOL 具有 YES 和 NO 两个值。
Objective-C 中的 BOOL 实际上⼀种对带符号的字符类型(signed char)的类型定义(typedef),它使⽤ 8 位的存储空间。通过 #define 把 YES 定义为 1,NO 定义为 0,。Objective-C 并不会将 BOOL 作为
仅能保存 YES 或 NO 值的真正布尔类型来处理。编译器仍将 BOOL 认作 8 位⼆进制数。这样会引发⼀个⼩问题:如果不⼩⼼将⼀个⼤于 1 字节的整数值赋给了⼀个 BOOL 变量,那么只有低位字节会⽤作 BOOL 值。
⾯向对象编程
⾯向对象编程(Object-Oriented Programming)的⾸字母缩写为 OOP,这是以⼀种编程技术,是为了编写模拟程序⽽开发的。OOP 是⼀种编程架构,可构建由多个对象组成的软件。
OOP 的⼀个关键概念 -> 间接:在代码中通过指针间接获取某个值,⽽不是直接获取。间接是 OOP 的核⼼,OOP 使⽤间接来调⽤某个函数,⽽不是直接调⽤。
类(class):是⼀种表⽰对象类型的结构体。对象通过它的类来获取⾃⾝的各种信息,尤其是执⾏每个操作需要运⾏的代码。
对象(object):是⼀种包含值和指向其类的隐藏指针的结构体。
实例(instance):是对象的另⼀种称呼。
消息(message):是对象可以执⾏的操作,⽤于通知对象去做什么。
⽅法(method):是为了响应消息⽽运⾏的代码。
xcode入门⽅法调度(method dispatcher):是 Objective-C 的⼀种机制,⽤于推测执⾏什么⽅法以响应某个特定的消息。
接⼝(interface):是类为对象提供的特性描述。
实现(implementation):是使接⼝能正常⼯作的代码。
继承
OOP 中的继承表明⼀个类从另⼀个类,它的⽗类或超类(superclass)中获取某个特性,是在两个类中建⽴关系的⼀种⽅式。
继承的类之间建⽴的关系为 "is a"(是⼀个)。
某些编程语⾔(例如 C++)具有多继承性,也就是⼀个类可以直接从两个或者多个类继承⽽来,但是 Objective-C 不⽀
持多继承。
超类 & ⽗类:是继承的类。
⼦类 & 孩⼦类:是执⾏继承的类。
当代码发送消息时,Objective-C 的⽅法调度机制将在当前的类中搜索相应的⽅法,如果⽆法在接收消息的对象的类⽂件中到相应的⽅法,它就会在该对象的⽗类中进⾏查。
self:是⼀个指向接收消息的对象的指针。
super:既不是参数也不是实例变量,⽽是 Objective-C 编译器提供的⼀种功能,当你向 super 发送消息时,实际上是在向该类的⽗类发送消息,如果⽗类中没有定义该消息,那么就会继续在继承链上⼀级中查。
self = [super init],[super init] 为了让⽗类将所有的初始化⼯作⼀次性完成,init 返回的值就是被初始化的对象,这么做是为了防⽌⽗类在初始化过程中返回的对象和⼀开始创建的不⼀致。
复合
复合(composition)是指将多个类组合在⼀起,配合使⽤。
Objective-C 中复合是通过包含作为实例变量的对象指针来实现的。
复合的类之间的建⽴的关系为 "has a"(有⼀个)。
内存管理
内存泄漏(leak memory):只分配⽽不释放内存。
对象⽣命周期:(通过 alloc 或者 new ⽅法实现),(接收消息并执⾏操作),(通过复合以及向⽅法传递参数),(被释放掉)。
引⽤技术(reference counting)& 保留计数(retain counting):每个对象都有⼀个和之相关联的整数,被称作它的引⽤计数器或保留计数器。当使⽤ alloc、new ⽅法或者通过 copy 创建⼀个对象时,对象的保留计数器值被设置为 1。增加对象的保留计数器的值,可以发送⼀条 retain 消息,反之,发送⼀条 release 消息。
⾃动释放池(autorelease pool):⽤来存放对象的池⼦(集合),并且能够⾃动释放。当给⼀个对象发送 autorelease 消息时,实际上是将该对象添加到了⾃动释放池中。当⾃动释放池被销毁时,会向该池中的所有对象发送 release 消息。
可以使⽤ NSMutableArray 编写⾃⼰的⾃动释放池,以容纳对象并在 dealloc ⽅法中向池中的所有对象发送 release 消息。
⾃动释放池被清理的时间是完全确定的:要么是在代码中你⼿动销毁,要么是使⽤ AppKit 时在事件循环(runloop)结束时销毁。你不必担⼼程序会随机地销毁⾃动释放池,也不必保留使⽤的每⼀个对象,因为在调⽤函数的过程中⾃动释放池不会被销毁。
内存管理规则:
1. 当你使⽤ new、alloc 或 copy ⽅法创建⼀个对象时,该对象的⾃动引⽤计数器的值为 1,当不再使⽤该对象,应该像该对象发送⼀条
release 或 autorelease 消息。
2. 当你通过其他⽅法获得⼀个对象时,假设该对象的⾃动计数器的值为1,⽽且已经被设置为⾃动释放,那么你就不需要执⾏任何操作来确保该
对象得到清理。如果打算拥有该对象,就需要保留它并确保在操作完成时释放它。
3. 如果保留了某个对象,就需要释放或⾃动释放该对象。必须保持 retain ⽅法和 release ⽅法使⽤次数相等。
垃圾回收:Objective-C 2.0 引⽤了⾃动内存管理机制,也称垃圾回收(仅⽀持 OS X 应⽤开发)。
启⽤垃圾回收以后,平常的内存管理命令全都变成了空操作指令。Objective-C 的垃圾回收器会定期检查变量和对象并且跟踪他们他们之间的指针,当发现没有任何变量指向某个指针时,就将该对象视为应该丢弃的垃圾。和⾃动释放池⼀样,垃圾回收也是在事件循环结束触发的。
⾃动引⽤计数(automatic reference counting,ARC)
ARC 会追踪你的对象并决定哪⼀个仍会使⽤⽽哪⼀个不会再⽤到,ARC 不是垃圾回收器,它是在编译时进⾏⼯作的,会在代码中插⼊合适的retain 和 release 语句。
ARC 只对可保留的对象指针(ROPs)有效可保留的对象指针主要有以下三种:
(1)代码块指针
(2)Objective-C 对象指针
(3)通过 __ attribute __((NSObject)) 类型定义的指针
对象初始化
分配对象:分配(allocation)就是从操作系统获得⼀块内存,并将其指定为存放对象的实例变量的位
置。向某个类发送 alloc 消息,就能为类分配⼀块⾜够⼤的内存,以存放该类的全部实例变量。同时 alloc ⽅法还顺便将这块内存区域全部初始化为 0。
初始化对象:与分配对应的操作是初始化,刚刚分配的对象并不能⽴即使⽤,你需要初始化后才能使⽤。初始化从操作系统取得⼀块内存⽤于存储对象,执⾏初始化操作的⽅法⼀般都会返回正在初始化的对象。
if (self = [super init]) 这句代码意味着 self 可能会发⽣改变,该声明中最先运⾏的代码是 [super init],其作⽤是让⽗类完成其⾃⾝的初始化⼯作。对于继承了 NSObject 的类来说,调⽤⽗类的init⽅法可以让 NSObject 执⾏它所需的所有操作,以便对象能够响应消息并处理保留计数器。⽽对于从其他类继承的类,通过这种⽅法可以实现⾃⾝的全新初始化。
self 参数是通过固定的距离寻实例变量所在的内存位置的。如果从 init ⽅法返回⼀个新的对象,则需要更新 self,以便其后的实例变量的引⽤可以被映射到正确的内存位置。self = [super init] 这个赋值操作只影响该init⽅法中的 self 的值,⽽不影响该⽅法范围以外的任何内容。
类别(category)
类别是⼀种为现有的类添加新⽅法的⽅法。
你可以在类别中添加属性,但是不能添加实例变量,⽽且属性必须是 @dynamic 类型的。
当类别中的⽅法与现有的⽅法重名时,类别具有更⾼的优先级。
类扩展(class extension)
不需要名字
可以在包含你的源代码的类中使⽤它
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论