您的位置:首页 > 移动开发 > Objective-C

objective-c 语法 细节(一)

2014-12-04 18:13 232 查看
三、动态绑定

1. 在objective-c中,一个对象内否调用指定的方法不是由编译器决定而是由运行时决定,这被称作是方法的动态绑定


2. 在objective-c里,对象不调用方法,而是接收消息,消息表达式为:
[reciver message];运行时系统首先确定接收者的类型(动态类型识别),然后根据消息名在类的方法列表里选择相依的方法执行,所以在源代码里消息也称为选择器(selector)

3. 消息函数的作用:
–首先通过第一个参数的receiver,找到它的isa指针,然后在isa
指向的Class
对象中使用第二个参数selector查
找方法;

– 如果没有找到,就使用当前Class对象中的新的isa
指针到上一级的父类的Class
对象中查找;

– 当找到方法后,再依据receiver的中的self
指针找到当前的对象,调用当前对象的具体实现的方法(IMP),然后传递参数,调用实现方法。

– 假如一直找到NSObject的Class
对象,也没有找到你调用的方法,就会报告不能识别发送消息的错误。

Objective-C在编译的时候,会根据方法的名字 (包括参数序列),生成一个用来区分这个方法的唯一的一个标示(ID),这个标示(ID)就是SEL类型的,在运行时候是通过方法的标示来查找方法的。只要方法的名字(包括参数序列)相同,那么它们的
ID都是相同的。可以通过@select()指示符获得方法的标示。SEL mydraw =@select(draw);
NSSelectorFromString(NSString*);根据方法名得到方法标识
(NSString*)NSStringFromSelector(SEL);得到SEL类型的方法名

Objetive-C中的Method结构
struct objc_method{
SEL method_name;//方法名
char *method_types; //方法地址
IMP method_imp; //方法地址(IMP)
};typedefobjc_method Method;

在运行时创建一个新类,只需要3步:
1、为 class pair分配存储空间 ,使用objc_allocateClassPair函数
2、增加需要的方法使用class_addMethod函数,增加实例变量用class_addIvar
3、用objc_registerClassPair函数注册这个类,以便它能被别人使用。
注意:使用这些函数请引#import <objc/runtime.h>

5.子类继承父类所有的方法。如果子类于父类同名方法,参数个数、类型和返回值一致,那么子类方法会覆盖父类方法,相当于C++中的虚函数进行重写override.

6.NSObject类实现了alloc,delloc,release,init方法.

alloc不需要在子类中重载

dealloc中释放在初始化中申请的内存,一般可能重载

release使对象的引用计数-1,当对象的引用计数为0时,系统自动调用对象的delloc方法释放对象的内存,此方法一般不需要重载。
init一般需要重载,初始化对象。

二、继承下的消息传递

继承下消息传递规则:先本类再父类,若一直到根类中都没有找到相应消息则报错。

三、组合

1.概念:如果一个类的实例变量是另外一个类的对象,则这两个类是“hasa”关系,表达的是整体-部分关系,但再objective-C中这样的实例变量只能是对象指针,不能是对象。这种方式叫做组合。

2.特别注意:注意组合方式下对象指针作为实例变量的initset方法,一般会重写dealloc方法释放内存。一定要遵循内存管理机制,防止内存泄漏。
????


方法重写

在Objective-c中,子类可继承父类中的方法,而不需要重新编写相同的方法,直接可以使用父类的方法。

但有时我们不想使用使用父类方法,而是想作一定的修改,怎么办呢?只要将子类中书写一个与父类具有相同的方法名、返回类型和参数,就可以将将父类的方法覆盖重写。比较简单。

方法重载

在Objective-c中,方法是不能重载的。也就是说我们不能在类中定义这样的两个方法:它们的名子相同,参数个数相同,参数类型不同,不同的返回值类型。否则Xcode会报错。

每个Object-C对象都隐藏着一个数据结构,它的第一个成员变量或者说实例变量是"isa"指针。 isa指针指向的是对象的类,这个类也是一个对象,有自己的权限,是根据类的定义编译而来的。类对象负责维护一个方法调度表,该表实际上是由指向类方法的指针组成的。类对象中还保留一个超类的指针,该指针又有自己的方法调度表和超类。
isa指针对消息分发机制和cocoa对象的动态能力很重要。

oc的运行环境(runtime library)完全是由c编写的。因此任何一个消息的派发,最终都会转化为几个c函数的调用。这样,oc和c语言可以完全的兼容了。

(3)属性和变量的用法

属性是用self.object,通过getter方法来调用的,可以在类外使用。而变量是通过_object来调用,只能在该类对应的implementation中使用,在类外不能使用。

下面看一下两种赋值操作:


[plain] view plaincopy

self.object = [[MyObject alloc] init];
object = [[MyObject alloc] init];

第一种的方式和@property(nonamtic,retain)有关,实际上是通过调用setter方法setObject来实现赋值的。第二种方式是简单的指针赋值,没有调用setter方法。

下面是retainCount的变化:

[plain] view plaincopy

MyObject *tmp = [[MyObject alloc] init];
self.object = tmp; //retainCount = 2
[tmp release]; //retainCount = 1
_object = [[MyObject alloc] init]; //retainCount = 1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: