OC多态性浅析

OC多态性浅析

小实验

假设有以下两个类classA与class B的声明与实现:

/// classA.h

#ifndef classA_h
#define classA_h

#import <Foundation/Foundation.h>

@interface classA : NSObject

-(void) printVar;

@end

#endif /* classA_h */
/// classB.h

#ifndef classB_h
#define classB_h

#import <Foundation/Foundation.h>
#import "classA.h"

@interface classB : classA

-(void) printVar;

@end

#endif /* classB_h */
/// classA.m

#import "classA.h"

@implementation classA

-(void) printVar
{
    NSLog(@"You called classA's method!");
}

@end
/// classB.m

#import "classB.h"

@implementation classB

-(void) printVar
{
    NSLog(@"You called classB's method!");
}

@end

在main中编写如下代码进行测试:

/// main.m

#import "classA.h"
#import "classB.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        classB *a = [classA new];
        classA *b = [classB new];
        [a printVar];
        [b printVar];
    }
    return 0;
}

这里我们声明了一个classB类型的对象a,但是用classA的构造器去初始化它;同时声明了一个classA类型的对象b,但是用classB的构造器去初始化它,那么执行代码,它们调用的究竟是哪一个类中的printVar函数呢?

答案如下:

实验结果

可见,a实际调用了classA中实现的方法,而b实际调用了classB中的方法。

这是因为在Objective-C中,方法的调用是根据对象的实际类型来确定的,而不是根据对象的声明类型(即变量的类型)来确定的。由于[classB new]返回的是classB类型的对象,所以对a调用printVar方法时,会调用classB中重载的printVar方法。

Objective-C中的多态性(Polymorphism)允许子类重写父类的方法,从而可以在运行时基于对象的实际类型选择不同的方法实现。这样可以实现更灵活和可扩展的代码设计。

与C++进行比较

在C++中,如果classBclassA的子类并且重载了classA的一个方法,那么如果使用classA类型的指针或引用指向一个classB类型的实例,并调用该方法,会根据指针或引用的静态类型(即声明类型)来决定调用哪个方法。

如果使用classA类型的指针或引用指向一个classB类型的实例,并调用重载的方法,那么实际调用的方法会根据指针或引用所指向的对象的动态类型(即运行时类型)来决定。

这就是C++的多态性(Polymorphism)概念,它允许通过基类的指针或引用来操作派生类的对象,并根据对象的实际类型调用合适的方法。与Objective-C类似,C++中的多态性可以实现灵活和可扩展的代码设计。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Objective-C中,属性的原子性是指属性在进行多线程访问时的安全性。当多个线程同时访问同一个属性时,如果不采取任何措施,可能会导致数据竞争和数据不一致等问题。为了保证属性的安全性,Objective-C提供了两种属性原子性的设置方式:原子性和非原子性。 - 原子性:当属性设置为原子性时,编译器会自动生成对应的互斥锁,保证每次只有一个线程可以访问该属性。这种方式可以保证属性的安全性,但会带来一定的性能开销。在使用原子性时,可以使用`atomic`关键字进行设置,如下所示: ``` @property (atomic, strong) NSString *name; ``` - 非原子性:当属性设置为非原子性时,多个线程可以同时访问该属性,可能会导致数据竞争和数据不一致等问题。这种方式可以提高性能,但需要开发者自己负责保证属性的安全性。在使用非原子性时,可以使用`nonatomic`关键字进行设置,如下所示: ``` @property (nonatomic, strong) NSString *name; ``` 需要注意的是,使用原子性并不能完全保证线程安全,因为编译器生成的互斥锁只能保证对属性的操作是原子的,但无法保证多个属性之间的操作是原子的。如果需要保证多个属性之间的原子性,需要使用其他的线程同步技术,如`@synchronized`关键字、GCD等。 总之,对于多线程场景下的属性访问,开发者需要根据具体情况选择合适的属性原子性设置方式,以确保属性的安全性和性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值