这是一篇一遍看不懂的文章!
1.熟悉Objective-C
Objective-C中的指针是用来指示对象的。
NSString *someStr = @“The string”;
声明了一个名为someStr的变量其类型是** NSString* **,此变量为指向NSString的指针。
再声明一个anotherStr
NSString *anotherStr = someStr;
此时,anotherStr和someStr都指向内存中的同一个地址,并没有执行拷贝。
对象所占内存分配在“堆空间。
2.消息机制
消息有“名称(name)”和“选择子(selector)”可以接受参数,可能还有返回值。
/*
*发送消息
* someObject 称为接受者
* messageName叫做选择子,选择子与参数合起来称为消息
*/
id returnValue = [someObject messageName:parameter];
/* 原型
* 这是个参数个数可变的函数,能接受两个或两个以上的参数,第一个参数代表接受者,第二个参数代表选择子
*/
void objc_msgSend(id self, SEL cmd, ...)
/*
* 编译器可以将上述例子转换成此方法
*/
id returnValue = objc_msgSend(someObject, @selector(messageName:), parameter);
这样就发送消息了,当接受者在所属类中找到与选择子名称相符合的方法,就跳至实现代码。若找不到,则沿着继承体系向上查找,找到就跳,找不到就执行“消息转发”机制。
注:Swift 和C语言均为静态绑定,OC为动态绑定。
OC在编译期间,无法调用底层的函数,需要在运行期才能调用出来。
3.计数工作原理
** 可以参考唐巧大神的理解iOS的内存管理 **
引用计数器进行保留计数:
- Reatain 递增引用计数
- release 递减保留计数
- autorelease 在自动释放池中递减保留计数
** 当引用计数降为0时,对象就回收了(deallocated),系统将其所占用的内存标记为可重用的,所有指向该对象的引用也无效了!此时不应再引用该对象,引用是程序可能会崩溃,取决于该内存区是否被重写!**
由于在ARC中,调用的是内存管理的底层方法,所以不可以覆写内存管理方法。ARC会自动优化retain,release,autorelease操作。
4.类对象与isa
描述Objective-C对象所用的数据结构定义在运行期程序库的头文件里,id类型也定义在这里:
typedef struct objc_object{
Class isa;
} *id;
对象定义
typedef struct objc_class *Class;
struct objc_class{
Class isa;
Class super_class;
const char *name;
long version;
long info;
long instance_size;
struct objc_ivar_list *ivars;
struct objc_method_list **methodLists;
struct objc_cache *cache;
struct objc_protocol_list *protocols;
}
每个实例都有一个指向Class对象的指针,isa,用以表明其类型。
Class 本身也是Objective-C对象,类对象所属的类型称为“元类”;因此类方法可以理解为类对象的实例方法。每个类仅有一个“类对象”,每个“类对象”仅有一个与之相关的“元类”;
网友评论