iOS 反射機(jī)制

一、簡介

動態(tài)編程機(jī)制可以讓Object-C語言更加靈活,Object-C提供了3種編程方式與運行環(huán)境交互。

1.直接通過Object-C的源代碼。這是最常見的方式

2.通過NSObject類中定義的方法進(jìn)行動態(tài)編程。

3.直接調(diào)用運行時函數(shù)進(jìn)行動態(tài)編程。

二、獲得Class與檢查繼承關(guān)系

1.獲得Class,先創(chuàng)建一個Animal對象

//通過類名獲取類
Class clazz = NSClassFromString(@"Animal");
NSLog(@"獲取到的類為:%@",clazz);
//通過類獲取類
Class clazz1 = Animal.class;
NSLog(@"獲取到的類為:%@",clazz1);
//通過對象獲取類
Animal * animal = [[clazz alloc] init];
Class clazz2 = animal.class;
NSLog(@"獲取到的類為:%@",clazz2);

輸出的結(jié)果為:
2016-06-15 13:30:26.217 繼承關(guān)系-test[10930:404401] 獲取到的類為:Animal

2016-06-15 13:30:26.218 繼承關(guān)系-test[10930:404401] 獲取到的類為:Animal

2016-06-15 13:30:26.218 繼承關(guān)系-test[10930:404401] 獲取到的類為:Animal

2.檢查繼承關(guān)系,創(chuàng)建兩個繼承自Animal的對象分別為Person和Dog;

Person * person = [[Person alloc] init];
Dog* dog = [[Dog alloc] init];
//判斷是否是該類或其子類的實例。
bool bl = [person isKindOfClass:[Animal class]];
//判斷是否是該類的實例
bool bl1 = [person isMemberOfClass:[Animal class]];
bool bl2 = [person isKindOfClass:[Dog class]];
NSLog(@"是否為該類或其子類:%d",bl);//1
NSLog(@"是否為為該類:%d",bl1);//0
NSLog(@"是否為該類或其子類:%d",bl2);//0

三、動態(tài)調(diào)用方法
1.判斷是否遵從了某項協(xié)議,指定animalDelegate協(xié)議

import <Foundation/Foundation.h>
@protocol animalDelegate <NSObject>

-(void)testFun;
@end

@interface Animal : NSObject

@end

若Dog類沒有遵從協(xié)議

import <Foundation/Foundation.h>
import "Animal.h"
@interface Dog : Animal

@end

調(diào)用方法

Dog* dog = [[Dog alloc] init];
//是否遵從了協(xié)議
bool bl = [dog conformsToProtocol:@protocol(animalDelegate)];
NSLog(@"%d",bl);//0

當(dāng)遵從了協(xié)議后

import <Foundation/Foundation.h>
import "Animal.h"
@interface Dog : Animal<animalDelegate>

@end

調(diào)用方法

Dog* dog = [[Dog alloc] init];
//是否遵從了協(xié)議
bool bl = [dog conformsToProtocol:@protocol(animalDelegate)];
NSLog(@"%d",bl);//1

2.判斷某個對象是否可以調(diào)用某個方法

//可以調(diào)用返回yes,不可以返回no
bl = [dog respondsToSelector:@selector(testFun)];
NSLog(@"%d",bl);

三、動態(tài)調(diào)用
給Dog類添加私有方法

-(NSString *)moveWithSpeed:(NSNumber *)speed{
  NSLog(@"移動");
  NSInteger num = [speed integerValue];
  return [NSString stringWithFormat:@"移動速度:%ld",num];
}

-(NSString *)runWithSpeed:(NSNumber*)speed{

  NSLog(@"快跑");
  NSInteger num = [speed integerValue];
  return [NSString stringWithFormat:@"快跑速度:%ld",num];
}

利用動態(tài)方法調(diào)用這兩個方法

Dog* dog = [[Dog alloc] init];
//動態(tài)調(diào)用方法
//方法一:performSelector
//參數(shù)可以傳1個或2個。若要傳入多個參數(shù)可以用集合的方式實現(xiàn)。
//返回值id
NSString * speed = [dog performSelector:@selector(moveWithSpeed:) withObject:[NSNumber numberWithInteger:5]];
NSLog(@"speed:%@",speed);
NSString * speed1 = [dog performSelector:@selector(moveWithSpeed:) withObject:@(5) withObject:nil];
NSLog(@"speed1:%@",speed1);

//方法二:objc_msgSend();
//需要在project-Build Setting- Enable Strict Checking of objc_msgSend Calls 選項設(shè)置為NO;
//可以傳入任意個參數(shù)。第一個為方法的調(diào)用者,  第二個為@selector(方法名),后邊為方法需要傳入的參數(shù)可以有多個。
//返回值為id,
NSString * speed2 = objc_msgSend(dog, @selector(runWithSpeed:),@(5),nil);
NSLog(@"speed2:%@",speed2);

//方法三:methodForSelector
//1.定義IMP指針 指針變量為runSpeed
NSString* (*runSpeed)(id,SEL,NSNumber*);
//2-1.methodForSelector:方法返回的是IMP。
//2-2.通過(NSString* (*)(id,SEL,NSNumber*))對返回的IMP進(jìn)行類型強轉(zhuǎn)。
runSpeed = (NSString* (*)(id,SEL,NSNumber*))[dog methodForSelector:@selector(runWithSpeed:)];
//通過runSpeed指針調(diào)用方法,并拿到返回值。
NSString * speed3 = runSpeed(dog,@selector(runWithSpeed:),@(100));
NSLog(@"speed3:%@",speed3);

輸出結(jié)果為:
2016-06-15 14:00:31.209 繼承關(guān)系-test[11662:423726] 移動

2016-06-15 14:00:31.209 繼承關(guān)系-test[11662:423726] speed:移動速度:5

2016-06-15 14:00:31.209 繼承關(guān)系-test[11662:423726] 移動

2016-06-15 14:00:31.209 繼承關(guān)系-test[11662:423726] speed1:移動速度:5

2016-06-15 14:00:31.209 繼承關(guān)系-test[11662:423726] 快跑

2016-06-15 14:00:31.210 繼承關(guān)系-test[11662:423726] speed2:快跑速度:5

2016-06-15 14:00:31.210 繼承關(guān)系-test[11662:423726] 快跑

2016-06-15 14:00:31.210 繼承關(guān)系-test[11662:423726] speed3:快跑速度:100

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • [{"reportDate": "2018-01-23 23:28:49","fluctuateCause": n...
    加勒比海帶_4bbc閱讀 885評論 1 2
  • 了解反射機(jī)制 Objective-C語言中的OC對象,都繼承自NSObject類。這個類為我們提供了一些基礎(chǔ)的方法...
    呦釋原點閱讀 1,427評論 0 7
  • 該文章屬于劉小壯原創(chuàng),轉(zhuǎn)載請注明:劉小壯[http://www.itdecent.cn/u/2de707c93d...
    劉小壯閱讀 46,775評論 45 151
  • 了解反射機(jī)制 Objective-C語言中的OC對象,都繼承自NSObject類。這個類為我們提供了一些基礎(chǔ)的方法...
    吾是小馬哥閱讀 323評論 0 0
  • 一般看來,我們對于“自我”最初和最基本的認(rèn)識是來源于“臉 ”,這個我們每天從鏡中看到的東西,是我們千真萬確的自己。...
    柔嘉閱讀 1,017評論 0 1

友情鏈接更多精彩內(nèi)容