个性化阅读
专注于IT技术分析

Objective-C类型检查和动态绑定详解 – Objective-C开发教程

上一章Objective-C开发教程请查看:Objective-C协议(Protocol)用法解析

众所周知,多态就是父类的指针指向子类的对象,那么这是如何做到的呢?这是OC的运行时runtime使程序在运行时才确定对象的类型,以及实际调用的方法,因此,这又叫做动态类型。

动态类型识别是通过isa指针实现的,运行时根据对象的isa指针寻找实际的类型,找到对应的属性或方法。

Objective-C的代码会被翻译成C的代码运行,其实也就是说类的所有信息(属性和方法)都会转成C相应的形式,在C层对OC的类结构进行控制可以得到所谓的动态特性,因而动态特性是因为编译器的存在,而动态类型是在运行时进行类型检查的。

OC中一个对象调用指定的方法不是由编译器决定,而是由运行时决定的,这又叫做动态绑定。相反类型在编译的时候进行检查的,又称为静态类型检查,显式使用指定类型的都会有静态类型检查,如int等。

动态绑定和id类型

一般的动态绑定实现使用id类型进行声明,id类型是一个类似void*的指针,也就是泛型,它的好处就是可以容纳任何类型的指针。

使用id类型声明的对象,编译器不会对其进行类型检查,只有在运行时才检查,并决定实际调用。不过即使如此,建议尽量少用,因为这样的代码很不清晰。

下面是一个动态绑定的例子:

#import <Foundation/Foundation.h>

@interface Square:NSObject {
   float area;
}

- (void)calculateAreaOfSide:(CGFloat)side;
- (void)printArea;
@end

@implementation Square
- (void)calculateAreaOfSide:(CGFloat)side {
   area = side * side;
}

- (void)printArea {
   NSLog(@"正方形面积: %f",area);
}

@end

@interface Rectangle:NSObject {
   float area;
}

- (void)calculateAreaOfLength:(CGFloat)length andBreadth:(CGFloat)breadth;
- (void)printArea;
@end

@implementation  Rectangle

- (void)calculateAreaOfLength:(CGFloat)length andBreadth:(CGFloat)breadth {
   area = length * breadth;
}

- (void)printArea {
   NSLog(@"长方形 %f",area);
}

@end

int main() {
   Square *square = [[Square alloc]init];
   [square calculateAreaOfSide:10.0];
   
   Rectangle *rectangle = [[Rectangle alloc]init];
   [rectangle calculateAreaOfLength:10.0 andBreadth:5.0];
   
   NSArray *shapes = [[NSArray alloc]initWithObjects: square, rectangle,nil];
   id object1 = [shapes objectAtIndex:0]; // 动态绑定
   [object1 printArea];
   
   id object2 = [shapes objectAtIndex:1]; // 动态绑定
   [object2 printArea];
   
   return 0;
}

类的前置声明

我们可以通过使用编译指令@class告诉编译器某个符号是一个类名,这种写法称为类的前置声明。多个类使用逗号隔开,以分号结束,前置声明也可以声明多次,如下例子:

@class NSString,NSArry,NSMutableArry;

@class Volume;

但是要注意,@class仅仅是告诉编译器符号是类名,这可以提高编译速度,但是使用到类的属性和方法,则需要导入头文件。

类的前置声明的主要使用是:累互相嵌套包含的时候,可以使用类的前置声明解决。

赞(0)
未经允许不得转载:srcmini » Objective-C类型检查和动态绑定详解 – Objective-C开发教程

评论 抢沙发

评论前必须登录!