【IOS 开发】Objective - C 面向对象高级特性 - 包装类 | 类处理 | 类别 | 扩展 | 协议 | 委托 | 异常处理 | 反射
一. Objective-C 對(duì)象簡(jiǎn)單處理
1. 包裝類
(1) 包裝類簡(jiǎn)介
NSValue 和 NSNumber :?
-- 通用包裝類 NSValue : NSValue 包裝單個(gè) short, int, long, float, char, id, 指針 等數(shù)據(jù);
-- NSNumber 包裝類 : 用于包裝 C 語(yǔ)言數(shù)據(jù)類型;
NSNumber 方法 :?
-- "+ numberWithXxx :" : 將特定類型的值包裝成 NSNumber;
-- "- initWithXxx :" : 先創(chuàng)建一個(gè) NSNumber 對(duì)象, 再用一個(gè)基本類型的值來(lái)初始化 NSNumber;
-- "- xxxValue :" : 返回 NSNumber 對(duì)象包裝的基本類型的值;
(2) 包裝類代碼示例
代碼示例 :?
/*************************************************************************> File Name: OCNSNumberDemo.m> Author: octopus> Mail: octopus_truth.163.com > Created Time: 六 10/ 3 12:50:15 2015************************************************************************/#import <Foundation/Foundation.h>int main(int argc, char * argv[]) {@autoreleasepool {NSNumber * num_int = [NSNumber numberWithInt : 10];NSNumber * num_double = [NSNumber numberWithDouble : 10];NSNumber * num_char = [NSNumber numberWithChar : 'A'];NSLog(@"number_int : %d, number_double : %g, num_char : %c", [num_int intValue], [num_double doubleValue], [num_char charValue]);NSNumber * num_int1 = [[NSNumber alloc] initWithInt : 10];NSNumber * num_double1 = [[NSNumber alloc] initWithDouble : 10];NSNumber * num_char1 = [[NSNumber alloc] initWithChar : 'A'];NSLog(@"number_int1 : %d, number_double1 : %g, num_char1 : %c",[num_int1 intValue], [num_double1 doubleValue], [num_char1 charValue]);} }
-- 執(zhí)行結(jié)果 :?
localhost:oc_object octopus$ clang -fobjc-arc -framework Foundation OCNSNumberDemo.m localhost:oc_object octopus$ ./a.out 2015-10-03 13:00:46.465 a.out[887:507] number_int : 10, number_double : 10, num_char : A 2015-10-03 13:00:46.468 a.out[887:507] number_int1 : 10, number_double1 : 10, num_char1 : A
2. description 方法
(1) description 方法簡(jiǎn)介
description 方法簡(jiǎn)介 : 類似于 Java 中 Object 的 toString() 方法;
-- 方法來(lái)源 : description 是 NSObject 中定義的, 所有的方法都有該方法;
-- 默認(rèn)方法 : description 默認(rèn)方法返回 <類名: 地址>;
-- 輸出對(duì)象 : NSLog() 函數(shù)輸出一個(gè)對(duì)象, 其實(shí)輸出的是該對(duì)象的 description 方法;
-- 示例 : OCPerson * person, 打印 [person description] 和 person 輸出結(jié)果是一樣的;
(2) description 示例代碼
示例代碼 :?
/*************************************************************************> File Name: OCDescriptionDemo.m> Author: octopus> Mail: octopus_truth.163.com > Created Time: 六 10/ 3 14:25:28 2015************************************************************************/ #import <Foundation/Foundation.h>@interface OCDescriptionDemo : NSObject @property (nonatomic, copy) NSString * name; @property (nonatomic, assign) int age; - (id) initWithNameAndAge : (NSString *) set_name setAge : (int) set_age; @end@implementation OCDescriptionDemo @synthesize name; @synthesize age; - (id) initWithNameAndAge : (NSString *) set_name setAge : (int) set_age {self.name = set_name;self.age = set_age;return self; } - (NSString *) description {NSString * des = [NSString stringWithFormat : @"<OCDescription[name = %@, age = %d]>", self.name, self.age];return des; } @endint main(int argc, char * argv[]) {@autoreleasepool {OCDescriptionDemo * description = [[OCDescriptionDemo alloc] initWithNameAndAge : @"Tom" setAge : 18];NSLog(@"%@", description);} }
-- 執(zhí)行結(jié)果 :?
localhost:oc_object octopus$ clang -fobjc-arc -framework Foundation OCDescriptionDemo.m localhost:oc_object octopus$ ./a.out 2015-10-03 14:50:18.665 a.out[970:507] <OCDescription[name = Tom, age = 18]>
3. == 或 isEqual : 方法
(1) "==" 運(yùn)算符
"==" 簡(jiǎn)介 :?
-- 作用 : 判斷兩個(gè)變量是否相等;
-- 前提 : 兩個(gè)變量都是基本類型, 兩個(gè)變量相等返回 true; 指針類型變量比較地址沒(méi)有任何意義;
(2) 常量池
常量池 :?
-- 作用 : 保證相同的字符串常量至右一個(gè), 不能出現(xiàn)多個(gè)相同的副本;
-- 例外 : 使用 [NSString stringWithFormat] 方法創(chuàng)建的字符串不會(huì)放入常量池;
(3) isEqual 方法
"isEqual" 方法簡(jiǎn)介 :?
-- 來(lái)源 : isEqual 方法是 NSObject 類提供的實(shí)例方法, 用于判斷相同類型的兩個(gè)變量是否相等;
-- 默認(rèn) : 默認(rèn)方法還是比較地址, 需要開(kāi)發(fā)者重寫(xiě)這個(gè)方法;
-- NSString 的 isEqual 方法 : NSString 的 isEqual 方法是判斷兩個(gè)字符串是否相等, 包含的字符串相同就會(huì)返回 true;
-- isEqualToString 方法 : 方法 : NSString 中定義的 isEqualToString 方法用于判斷當(dāng)前字符串 與 另一個(gè)字符串的字符串序列是否相等;
重寫(xiě) isEqual 方法標(biāo)準(zhǔn) :?
-- 自反性 : 對(duì)象 x, [x isEqual : x] 必須返回 true;
-- 對(duì)稱性 : 對(duì)象 x 和 y, 如果 [x isEqual : y] 返回值 必須與 [y isEqual : x] 返回值相同;
-- 傳遞性 : 對(duì)象 x , y 和 z, [x isEqual : y] = true, [y isEqual : z] = true, 那么 x z 也相等;
-- 一致性 : x , y 對(duì)象無(wú)論調(diào)用多少次, 返回值結(jié)果都應(yīng)該保持一致;
-- nil 對(duì)比 : 如果 x 不是 nil, [x isEqual : nil] 必須返回 false;
(4) "==" 和 "isEqual" 示例源碼
示例源碼 :?
/*************************************************************************> File Name: OCEqual.m> Author: octopus> Mail: octopus_truth.163.com > Created Time: 六 10/ 3 16:07:56 2015************************************************************************/ #import <Foundation/Foundation.h>@interface OCEqual : NSObject @property (nonatomic, copy) NSString * name; @property (nonatomic, assign) int age;- (id) initWithName : (NSString *) set_name setAge : (int) set_age; @end@implementation OCEqual @synthesize name; @synthesize age;- (id) initWithName : (NSString *) set_name setAge : (int) set_age {self.name = set_name;self.age = set_age;return self; }- (BOOL) isEqual : (id) other {if(self == other)return YES;if(other != nil && [other isMemberOfClass : OCEqual.class]){OCEqual * equal = (OCEqual *) other;return [self.name isEqual : equal.name] && (self.age == equal.age);}return NO; } @endint main(int argc, char * argv[]) {@autoreleasepool {int int_a = 10;int double_a = 10.0;NSLog(@"int_a == double_a : %d", (int_a == double_a));NSString * str_a = @"Octopus";NSString * str_b = @"Octopus";NSString * str_c = [NSString stringWithFormat : @"Octopus"];NSString * str_d = [NSString stringWithFormat : @"Octopus"];NSLog(@"str_a == str_b : %d, str_c == str_d : %d, [str_c isEqual : str_d] : %d", str_a == str_b, str_c == str_d, [str_c isEqual : str_d]);OCEqual * equal_a = [[OCEqual alloc] initWithName : @"Tom" setAge : 18];OCEqual * equal_b = [[OCEqual alloc] initWithName : @"Jerry" setAge : 20];OCEqual * equal_c = [[OCEqual alloc] initWithName : @"Jerry" setAge : 20];NSLog(@"[equal_a isEqual : equal_b] : %d, [equal_b isEqual : equal_c] : %d", [equal_a isEqual : equal_b], [equal_b isEqual : equal_c]);} }
-- 執(zhí)行結(jié)果 :?
localhost:oc_object octopus$ clang -fobjc-arc -framework Foundation OCEqual.m localhost:oc_object octopus$ ./a.out 2015-10-03 16:58:35.690 a.out[1168:507] int_a == double_a : 1 2015-10-03 16:58:35.693 a.out[1168:507] str_a == str_b : 1, str_c == str_d : 0, [str_c isEqual : str_d] : 1 2015-10-03 16:58:35.693 a.out[1168:507] [equal_a isEqual : equal_b] : 0, [equal_b isEqual : equal_c] : 1
二. 類別 與 擴(kuò)展
1. Category 類別
(1) 擴(kuò)展類簇需求
類簇?cái)U(kuò)展需求 : 開(kāi)發(fā)過(guò)程中有時(shí)需要擴(kuò)展類行為;
-- 繼承 : 通過(guò)繼承, 子類在父類基礎(chǔ)上添加方法 或者 重寫(xiě)父類方法;
-- 問(wèn)題 : 如果想要為父類增加一個(gè)方法, 子類同時(shí)也繼承這些方法, 此時(shí)使用繼承就滿足不了這個(gè)功能了;
-- 類簇 : OC 中沒(méi)有接口, 需要接口時(shí), 就會(huì)選擇定義一個(gè)父類, 以該父類派生 N 個(gè)子類, 該系列的類被成為 類簇;
-- 類簇?cái)U(kuò)展方法 : 為父類增加方法, 類簇中得子類同時(shí)也增加該方法, 擴(kuò)展類簇中得父類是最合適的方法;
(2) Category 類別
類別 (category) 簡(jiǎn)介 :?
-- 作用 : 為現(xiàn)有類添加方法, 不需要訪問(wèn)原有類代碼, 不需要繼承;
-- 有點(diǎn) : 動(dòng)態(tài)地為現(xiàn)有類添加方法, 將類定義模塊化 分布到多個(gè)文件中;
(3) Category 類別 接口 語(yǔ)法格式
類別 (category) 接口部分語(yǔ)法格式 :?
-- 接口文件類命名 : "類名+類別名.h", 如 要擴(kuò)展 OCPerson 類, 類別名為 SB, 那么接口文件名就是 "OCPerson+SB.h";
-- 示例 :?
@interface 已有類 (類別名) //方法定義 ... @end
-- 類別名 : 必須是項(xiàng)目中沒(méi)有的類, 定義類別時(shí)使用的類名, 必須是已有的類;
-- 圓括號(hào) : 類別名 定義在 需要擴(kuò)展的已有類之后, 必須使用圓括號(hào)括起來(lái);
-- 定義內(nèi)容 : 類別中一般情況下只定義方法;
(4) Category 類別 實(shí)現(xiàn)類 語(yǔ)法格式
類別 (category) 實(shí)現(xiàn)部分語(yǔ)法格式 :?
-- 實(shí)現(xiàn)類文件命名 : "類名+類別名.m", 如 要擴(kuò)展 OCPerson 類, 類別名為 SB, 那么接口文件名就是 "OCPerson+SB.m";
-- 示例 :?
@implementation 已有類 (類別名) //方法定義 ... @end
(5) Category 類別 注意點(diǎn)
注意事項(xiàng) :?
-- 影響范圍 : 通過(guò) category 添加新方法后, 會(huì)影響到 指定的被擴(kuò)展的類, 同時(shí)也會(huì)影響到其子類;
-- 多個(gè)類別 : 一個(gè)類可以 對(duì)應(yīng)多個(gè)類別, 這些類別都可以為類增加方法定義;
-- 類別優(yōu)點(diǎn) :?進(jìn)行模塊化設(shè)計(jì),?調(diào)用私有方法,?實(shí)現(xiàn)非正式協(xié)議;
(6) Category 擴(kuò)展 NSNumber 示例
NSNumber 擴(kuò)展示例 : 為其添加一個(gè)計(jì)算圓面積的方法;
--?NSNumber+SB.h :?
/*************************************************************************> File Name: NSNumber+SB.h> Author: octopus> Mail: octopus_truth.163.com > Created Time: 六 10/ 3 18:58:53 2015************************************************************************/ #import <Foundation/Foundation.h> @interface NSNumber (SB) - (NSNumber *) circleAera : (double) radius; @end
--? NSNumber+SB.m :?
/*************************************************************************> File Name: NSNumber+SB.m> Author: octopus> Mail: octopus_truth.163.com > Created Time: 六 10/ 3 19:02:05 2015************************************************************************/#import "NSNumber+SB.h"@implementation NSNumber (SB)- (NSNumber *) circleAera : (double) radius{double aera = 3.1415926 * radius * radius;return [NSNumber numberWithDouble : aera];}@end
--? NSNumber+SBTest.m :?
/*************************************************************************> File Name: NSNumber+SBTest.m> Author: octopus> Mail: octopus_truth.163.com > Created Time: 六 10/ 3 19:08:19 2015************************************************************************/ #import <Foundation/Foundation.h> #import "NSNumber+SB.h"int main(int argc, char * argv[]) {@autoreleasepool {NSNumber * num = [NSNumber numberWithInt : 3];NSNumber * circleAera = [num circleAera : 1];NSLog(@"%@", circleAera);} }
-- 執(zhí)行結(jié)果 :?
localhost:oc_object octopus$ clang -fobjc-arc -framework Foundation NSNumber+SB.m NSNumber+SBTest.m localhost:oc_object octopus$ ./a.out 2015-10-03 19:18:13.625 a.out[1333:507] 3.1415926
2. Category 類別實(shí)際用法
(1) 類的模塊化設(shè)計(jì)
模塊化設(shè)計(jì)簡(jiǎn)介 :?
-- 實(shí)現(xiàn)部分唯一 : 定義一個(gè)類是, 使用 "類名.h" 定義接口部分, 使用 "類名.m" 定義實(shí)現(xiàn)部分, 不能將實(shí)現(xiàn)部分定義在多個(gè) ".m" 后綴 文件中;
-- 文件臃腫 : 如果類很大, 將所有的代碼放在一個(gè) "類名.m" 文件中, 非常難維護(hù);
(2) 調(diào)用私有方法
私有方法調(diào)用簡(jiǎn)介 :?
-- 私有方法 : 接口中沒(méi)有定義, 在實(shí)現(xiàn)部分定義的方法是 私有方法, 不允許被外部調(diào)用;
-- 調(diào)用私有方法一 : 使用 NSObject 的 "performSelector :"執(zhí)行調(diào)用, 也是可以調(diào)用私有方法的, 不過(guò)此方法會(huì)避開(kāi)語(yǔ)法檢查, 導(dǎo)致未知問(wèn)題;
(3) 調(diào)用私有方法 代碼示例
代碼示例 :?
-- OCPrivate.h :?
/*************************************************************************> File Name: OCPrivate.h> Author: octopus> Mail: octopus_truth.163.com > Created Time: 日 10/ 4 06:55:34 2015************************************************************************/ #import <Foundation/Foundation.h>@interface OCPrivate : NSObject @property (nonatomic, copy) NSString * name; -(void) info; @end
-- OCPrivate.m :?
/*************************************************************************> File Name: OCPrivate.m> Author: octopus> Mail: octopus_truth.163.com > Created Time: 日 10/ 4 06:57:48 2015************************************************************************/ #import "OCPrivate.h"@implementation OCPrivate @synthesize name;- (void) info {NSLog(@"name : %@", self.name); }- (void) speak {NSLog(@"Hello World !"); } @end
-- OCPrivate+SB.h :?
/*************************************************************************> File Name: OCPrivate+SB.h> Author: octopus> Mail: octopus_truth.163.com > Created Time: 日 10/ 4 07:19:35 2015************************************************************************/ #import "OCPrivate.h" @interface OCPrivate (SB) - (void) speak; @end
-- OCPrivateTest.m :?
/*************************************************************************> File Name: OCPrivateTest.m> Author: octopus> Mail: octopus_truth.163.com > Created Time: 日 10/ 4 07:22:04 2015************************************************************************/ #import "OCPrivate+SB.h"int main(int argc, char * argv[]) {@autoreleasepool{OCPrivate * priva = [[OCPrivate alloc] init];priva.name = @"Tom";[priva info];[priva speak];} }
3. extension 擴(kuò)展
(1) extension 簡(jiǎn)介
extension 簡(jiǎn)介 :?
-- 作用 : 擴(kuò)展相當(dāng)于匿名類別;
-- 語(yǔ)法 :?
@interface 已有類 () {//實(shí)例變量 ... } // 方法定義 ... @end
-- 用法 : 定義兩個(gè)頭文件, OCExtension.h 和 OCExtension+speak.h, OCExtension.m 導(dǎo)入 OCExtension+speak.h 頭文件;
(2) extension 源碼示例
源碼示例 :?
-- OCExtension.h :?
/*************************************************************************> File Name: OCExtension.h> Author: octopus> Mail: octopus_truth.163.com > Created Time: 日 10/ 4 08:18:43 2015************************************************************************/ #import <Foundation/Foundation.h> @interface OCExtension : NSObject @property (nonatomic, copy) NSString * name; @property (nonatomic, assign) int age; - (void) info; @end
-- OCExtension+speak.h :?
/*************************************************************************> File Name: OCExtension+speak.h> Author: octopus> Mail: octopus_truth.163.com > Created Time: 日 10/ 4 08:31:37 2015************************************************************************/ #import "OCExtension.h" @interface OCExtension () @property (nonatomic, copy) NSString * home; - (void) speak : (NSString *) content; @end
-- OCExtension.m :?
/*************************************************************************> File Name: OCExtension.m> Author: octopus> Mail: octopus_truth.163.com > Created Time: 日 10/ 4 08:27:50 2015************************************************************************/ #import "OCExtension+speak.h" @implementation OCExtension @synthesize name; @synthesize age; @synthesize home; - (void) info {NSLog(@"info : name : %@ , age : %d", self.name, self.age); } - (void) speak : (NSString *) content {NSLog(@"%@ speak %@", self.name, content); } @end
-- OCExtensionTest.m :?
/*************************************************************************> File Name: OCExtensionTest.m> Author: octopus> Mail: octopus_truth.163.com > Created Time: 日 10/ 4 13:20:42 2015************************************************************************/ #import "OCExtension+speak.h"int main(int argc, char * argv[]) {@autoreleasepool {OCExtension * extension = [[OCExtension alloc] init];extension.name = @"Tom";extension.age = 18;extension.home = @"China";[extension info];[extension speak : @"Are you fucking kidding me"];} }
三. 協(xié)議 與 委托
1. 類別實(shí)現(xiàn)非正式協(xié)議
(1) 非正式協(xié)議簡(jiǎn)介
協(xié)議簡(jiǎn)介 :
-- 作用 : OC 中得協(xié)議作用相當(dāng)于其它語(yǔ)言中得接口;
-- 協(xié)議表現(xiàn) : 協(xié)議定義的是 多個(gè)類 共同的行為規(guī)范,?通常定義一組公用方法, 這些方法都沒(méi)有實(shí)現(xiàn), 方法由類來(lái)實(shí)現(xiàn);
非正式協(xié)議簡(jiǎn)介 :?
-- 創(chuàng)建 NSObject 類別 : 以 NSObject 為基礎(chǔ), 為 NSObject 創(chuàng)建類別, 為該類別指定新增方法, 即給所有的 NSObject 子類增加了新方法;
-- 實(shí)現(xiàn) NSObject 類別 : 實(shí)現(xiàn) NSObject 類別時(shí), 實(shí)現(xiàn)該列別下地所有方法, 即之前在 NSObject 類別中定義的方法;
(2) 非正式協(xié)議代碼示例
非正式協(xié)議代碼示例 :?
-- NSObject+speak.h : 為 NSObject 定義的類別接口, 所有的繼承 NSObject 的類都必須實(shí)現(xiàn)該類別中得抽象方法;
/*************************************************************************> File Name: NSObject+speak.h> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 10/ 5 08:55:48 2015************************************************************************/ #import <Foundation/Foundation.h> @interface NSObject (speak) - (void) speak; @end
-- OCNSObjectProtocal.h : NSObject 子類接口, 該接口繼承 NSObject 類, 注意 需要導(dǎo)入 NSObject+speak.h 頭文件;
/*************************************************************************> File Name: OCNSObjectProtocal.h> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 10/ 5 09:00:37 2015************************************************************************/ #import "NSObject+speak.h" @interface OCNSObjectProtocal : NSObject @end
-- OCNSObjectProtocal.m : OCNSObjectProtocal 實(shí)現(xiàn)類, 在該實(shí)現(xiàn)類中必須實(shí)現(xiàn) 類別中定義的 speak 方法;
/*************************************************************************> File Name: OCNSObjectProtocal.m> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 10/ 5 09:02:03 2015************************************************************************/ #import "OCNSObjectProtocal.h" @implementation OCNSObjectProtocal - (void) speak {NSLog(@"Speak Hello World"); } @end
-- OCNSObjectProtocalTest.m : 測(cè)試類, 測(cè)試以上代碼是否可以執(zhí)行;
/*************************************************************************> File Name: OCNSObjectProtocalTest.m> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 10/ 5 09:04:31 2015************************************************************************/ #import "OCNSObjectProtocal.h"int main(int argc, char * argv[]) {@autoreleasepool {OCNSObjectProtocal * obj = [[OCNSObjectProtocal alloc] init];[obj speak];} }
-- 執(zhí)行結(jié)果 :?
bogon:oc_object octopus$ clang -fobjc-arc -framework Foundation OCNSObjectProtocal.m OCNSObjectProtocalTest.m bogon:oc_object octopus$ ./a.out 2015-10-05 09:06:44.895 a.out[2100:507] Speak Hello World
2. 定義正式協(xié)議
(1) 正式協(xié)議語(yǔ)法
正式協(xié)議語(yǔ)法 :?
-- 語(yǔ)法 :?
@protocol 協(xié)議名稱 <父類協(xié)議1, 父類協(xié)議2 ...> // N 個(gè)協(xié)議方法 @end
-- 協(xié)議名稱規(guī)范 : 采用與類名相同的命名規(guī)則;
-- 繼承規(guī)則 : 一個(gè)協(xié)議 可以有 多個(gè)父類協(xié)議, 協(xié)議只能繼承協(xié)議, 不能繼承類;
-- 方法規(guī)則 : 協(xié)議中只能定義抽象方法, 不能定義方法實(shí)現(xiàn), 既可以定義類方法, 也可以定義實(shí)例方法;
(2) 實(shí)現(xiàn)協(xié)議
實(shí)現(xiàn)協(xié)議語(yǔ)法 :?
-- 語(yǔ)法 :?
@interface 類名 : 父類 <協(xié)議1, 協(xié)議2...>-- 對(duì)應(yīng)關(guān)系 : 一個(gè)類可以實(shí)現(xiàn)多個(gè)協(xié)議;(3) 聲明協(xié)議變量
變量聲明 :
-- 使用原變量聲明 : "變量名 * 對(duì)象名" , 如 "OCCat * cat";
-- 使用協(xié)議定義 : "NSObject <協(xié)議1, 協(xié)議2 ...> * 對(duì)象名", 如 "NSObject<OCProtocolCat> * cat";
-- 使用 id 類型定義 : "id<OCProtocolCat> 對(duì)象名", 如 "id<OCProtocolCat> cat", 注意此處沒(méi)有指針標(biāo)識(shí);?
(4) 正式協(xié)議實(shí)現(xiàn)代碼
代碼示例 :?
-- OCAnimalProtocol.h : 最基礎(chǔ)的協(xié)議1;
/*************************************************************************> File Name: OCAnimalProtocol.h> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 10/ 5 09:25:41 2015************************************************************************/ #import <Foundation/Foundation.h> @protocol OCAnimalProtocol - (void) name; - (void) age; @end
-- OCProtocolBord.h : 最基礎(chǔ)的協(xié)議2;
/*************************************************************************> File Name: OCProtocolBord.h> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 10/ 5 09:40:08 2015************************************************************************/ #import <Foundation/Foundation.h> @protocol OCProtocolBord - (void) fly; @end
-- OCProtocolCat.h : 該協(xié)議實(shí)現(xiàn)了 上面的兩個(gè)協(xié)議;
/*************************************************************************> File Name: OCProtocolCat.h> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 10/ 5 09:45:17 2015************************************************************************/#import <Foundation/Foundation.h> #import "OCAnimalProtocol.h" #import "OCProtocolBord.h"@protocol OCProtocolCat <OCAnimalProtocol, OCProtocolBord> - (void) purr; @end
-- OCCat.h : OCCat 類接口部分, 生命了該類 實(shí)現(xiàn)協(xié)議 OCProtocolCat 協(xié)議;
/*************************************************************************> File Name: OCCat.h> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 10/ 5 09:50:21 2015************************************************************************/#import "OCProtocolCat.h"@interface OCCat : NSObject <OCProtocolCat> @end
-- OCCat.m : OCCat 類實(shí)現(xiàn)部分;
/*************************************************************************> File Name: OCCat.m> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 10/ 5 09:52:45 2015************************************************************************/#import "OCCat.h"@implementation OCCat- (void) name{NSLog(@"name : cat");}- (void) age{NSLog(@"age : 18");}- (void) fly{NSLog(@"cat fly");}- (void) purr{NSLog(@"cat purr");}@end
-- OCProtocolTest.m : 以上類的功能測(cè)試類;
/*************************************************************************> File Name: OCProtocolTest.m> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 10/ 5 10:14:38 2015************************************************************************/#import <Foundation/Foundation.h> #import "OCCat.h"int main(int argc, char * argv[]) {@autoreleasepool {OCCat * cat = [[OCCat alloc] init];[cat name];[cat age];[cat fly];[cat purr];NSObject<OCProtocolCat> * cat1 = [[OCCat alloc] init];[cat1 name];[cat1 age];[cat1 fly];[cat1 purr];id<OCAnimalProtocol> cat2 = [[OCCat alloc] init];[cat2 name];[cat2 age];} }
-- 執(zhí)行結(jié)果 :?
bogon:6.4 octopus$ clang -fobjc-arc -framework Foundation OCCat.m OCProtocolTest.m bogon:6.4 octopus$ ./a.out 2015-10-05 10:24:20.099 a.out[2271:507] name : cat 2015-10-05 10:24:20.101 a.out[2271:507] age : 18 2015-10-05 10:24:20.102 a.out[2271:507] cat fly 2015-10-05 10:24:20.102 a.out[2271:507] cat purr 2015-10-05 10:24:20.102 a.out[2271:507] name : cat 2015-10-05 10:24:20.103 a.out[2271:507] age : 18 2015-10-05 10:24:20.103 a.out[2271:507] cat fly 2015-10-05 10:24:20.104 a.out[2271:507] cat purr 2015-10-05 10:24:20.104 a.out[2271:507] name : cat 2015-10-05 10:24:20.104 a.out[2271:507] age : 18
3. 委托
委托概念 : 定義協(xié)議的類 將 定義協(xié)議的方法 委托給 實(shí)現(xiàn)協(xié)議的類;
-- 好處 : 類具有更好地通用性, 具體的動(dòng)作交給實(shí)現(xiàn)類完成;
創(chuàng)建工程 :?
-- 歡迎界面, 選擇 Create a new xcode project;
-- 創(chuàng)建一個(gè) OS 下地 Cocoa Application :?
-- 創(chuàng)建 工程 :?
項(xiàng)目中得源文件 :?
-- main.m : main() 函數(shù)入口;
-- OCAppDelegate.h : OCAppDelegate 類接口文件;
-- OCAppDelegate.m : OCAppDelegate 類實(shí)現(xiàn)部分;
代碼示例 :?
-- 前置操作 : 刪除 MainMenu.xib 文件, 刪除 Hello-Info.plist 中的 MainMenu 選項(xiàng);
-- OCAppDelegate.h :?
// // OCAppDelegate.h // Hello // // Created by octopus on 15-10-5. // Copyright (c) 2015年 www.octopus.org.cn. All rights reserved. //#import <Cocoa/Cocoa.h>//該接口 實(shí)現(xiàn) NSApplicationDelegate 協(xié)議 @interface OCAppDelegate : NSObject <NSApplicationDelegate> //定義窗口 @property (strong) NSWindow *window;@end
-- OCAppDelegate.m :?
// // OCAppDelegate.m // Hello // // Created by octopus on 15-10-5. // Copyright (c) 2015年 www.octopus.org.cn. All rights reserved. //#import "OCAppDelegate.h"@implementation OCAppDelegate @synthesize window;//應(yīng)用加載完成時(shí)回調(diào)的方法 - (void)applicationWillFinishLaunching:(NSNotification *)notification {//設(shè)置窗口屬性self.window = [[NSWindow alloc] initWithContentRect :NSMakeRect(300, 300, 320, 200)styleMask:(NSTitledWindowMask | NSMiniaturizableWindowMask |NSClosableWindowMask)backing:NSBackingStoreBuffereddefer:NO];self.window.title = @"Hello World";//設(shè)置文本框?qū)傩訬STextField * label = [[NSTextField alloc] initWithFrame:NSMakeRect(60, 120, 200, 60)];[label setSelectable:YES];[label setBezeled:YES];[label setDrawsBackground:YES];[label setStringValue:@"HELLO WORLD"];//設(shè)置按鈕屬性NSButton * button = [[NSButton alloc] initWithFrame:NSMakeRect(120, 40, 80, 30)];button.title = @"OCTOPUS";[button setBezelStyle:NSRoundedBezelStyle];[button setBounds:NSMakeRect(120, 40, 80, 30)];//將 文本框 和 按鈕 添加到窗口中[self.window.contentView addSubview:label];[self.window.contentView addSubview:button]; }//加載完成時(shí)回調(diào)的方法 - (void) applicationDidFinishLaunching:(NSNotification *)notification {//顯示窗口[self.window makeKeyAndOrderFront:self]; }@end
-- main.m :?
// // main.m // Hello // // Created by octopus on 15-10-5. // Copyright (c) 2015年 www.octopus.org.cn. All rights reserved. //#import <Cocoa/Cocoa.h> #import "OCAppDelegate.h"int main(int argc, const char * argv[]) {@autoreleasepool {//創(chuàng)建一個(gè)實(shí)現(xiàn)了 NSApplicationDelegate 協(xié)議的對(duì)象OCAppDelegate * delegate = [[OCAppDelegate alloc] init];//獲取 NSApplication 單例對(duì)象[NSApplication sharedApplication];//設(shè)置代理, 將處理方法委托給 delegate[NSApp setDelegate : delegate];//開(kāi)始運(yùn)行程序return NSApplicationMain(argc, argv);}}
-- 運(yùn)行結(jié)果 :?
四. 異常處理
1. @try ... @catch ... @finally ... 異常捕捉
(1) Objective-C 異常機(jī)制
Objective-C 異常機(jī)制 :?
-- 作用 : 開(kāi)發(fā)者將引發(fā)異常的代碼放在 @try 代碼塊中, 程序出現(xiàn)異常 使用 @catch 代碼塊進(jìn)行捕捉;
-- 每個(gè)代碼塊作用 : @try 代碼塊存放可能出現(xiàn)異常的代碼, @catch 代碼塊 異常處理邏輯, @finally 代碼塊回收資源;
-- 語(yǔ)法示例 :?
@try {// 業(yè)務(wù)邏輯 } @catch (異常類型名1 ex) {//異常處理代碼 } @catch (異常類型名2 ex) {//異常處理代碼 } // 可以捕捉 N 個(gè) 異常 ... @finally {//回收資源 }
(2) Objective-C 異常處理過(guò)程
異常處理過(guò)程 :?
-- 生成異常對(duì)象 : @try 中出現(xiàn)異常, 系統(tǒng)會(huì)生成一個(gè)異常對(duì)象, 該對(duì)象提交到系統(tǒng)中 系統(tǒng)就會(huì)拋出異常;
-- 異常處理流程 : 運(yùn)行環(huán)境接收到 異常對(duì)象時(shí), 如果存在能處理該異常對(duì)象的 @catch 代碼塊, 就將該異常對(duì)象交給 @catch 處理, 該過(guò)程就是捕獲異常, 如果沒(méi)有 @catch 代碼塊處理異常, 程序就會(huì)終止;
-- @catch 代碼塊捕獲過(guò)程 : 運(yùn)行環(huán)境接收到 異常對(duì)象 時(shí), 會(huì)依次判斷該異常對(duì)象類型是否是 @catch 代碼塊中異?;蚱渥宇悓?shí)例, 如果匹配成功, 被匹配的 @catch 就會(huì)處理該異常, 都則就會(huì)跟下一個(gè) @catch 代碼塊對(duì)比;
-- @catch 處理異常 : 系統(tǒng)將異常對(duì)象傳遞給 @catch 形參, @catch 通過(guò)該形參獲取異常對(duì)象詳細(xì)信息;
其它注意點(diǎn) :?
-- @try 與 @catch 對(duì)應(yīng)關(guān)系 : 一個(gè) @try 代碼塊 可以對(duì)應(yīng) 多個(gè) @catch 代碼塊;?
-- {} 省略問(wèn)題 : 異常捕獲的 @try @catch @finally 的花括號(hào)不可省略;
NSException 異常類 :?
-- 簡(jiǎn)介 : NSException 是 OC 中所有異常的父類;
-- 位置永遠(yuǎn)在最后 : @catch 代碼塊捕獲異常時(shí)查看 異常對(duì)象類型是否是 捕獲的異常類型 或者其子類, 一旦放在開(kāi)頭, 后面的異常永遠(yuǎn)不可能捕獲;
(3) 異常信息訪問(wèn)
異常信息訪問(wèn) :?
-- name : 返回異常的詳細(xì)名稱;
-- reason : 返回異常引發(fā)的原因;
-- userInfo : 返回異常的用戶信息, 一個(gè) NSDictionary 對(duì)象;
(4) 使用 finally 回收資源
回收物理資源 : @try 代碼塊中打開(kāi)物理資源, 數(shù)據(jù)庫(kù) 網(wǎng)絡(luò)連接 文件等, 都需要回收, 在 @finally 中回收最好;
-- 回收位置分析 : 如果再 @try 中回收, 出現(xiàn)異常, 異常后面的代碼無(wú)法執(zhí)行, @catch 中回收, 如果不出現(xiàn)異常, 該代碼塊就不會(huì)執(zhí)行; 因此 finally 中是必執(zhí)行的代碼, 在這里回收最合適;
(5) 異常代碼示例
異常代碼示例 :?
-- OCAnimal.h : 定義協(xié)議;
/*************************************************************************> File Name: OCAnimal.h> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 10/ 5 16:30:02 2015************************************************************************/ #import <Foundation/Foundation.h>@protocol OCAnimal @optional - (void) run; @end
-- OCCat.h : 定義 OCCat 接口;
/*************************************************************************> File Name: OCCat.h> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 10/ 5 16:33:59 2015************************************************************************/ #import "OCAnimal.h"@interface OCCat : NSObject <OCAnimal> @end
-- OCCat.m : 定義 OCCat 實(shí)現(xiàn)類;
/*************************************************************************> File Name: OCCat.m> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 10/ 5 16:36:36 2015************************************************************************/ #import "OCCat.h"@implementation OCCat @end
-- OCCatTest.m : 測(cè)試類;
/*************************************************************************> File Name: OCCatTest.m> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 10/ 5 16:38:01 2015************************************************************************/ #import "OCCat.h"int main(int argc, char * argv[]) {@autoreleasepool {OCCat * cat = [[OCCat alloc] init];[cat run];} }
-- 執(zhí)行結(jié)果 :?
bogon:6.5 octopus$ clang -fobjc-arc -framework Foundation OCCat.m OCCatTest.m bogon:6.5 octopus$ ./a.out 2015-10-05 16:39:23.589 a.out[2985:507] -[OCCat run]: unrecognized selector sent to instance 0x7fd7a3401870 2015-10-05 16:39:23.611 a.out[2985:507] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[OCCat run]: unrecognized selector sent to instance 0x7fd7a3401870' *** First throw call stack: (0 CoreFoundation 0x00007fff903dd25c __exceptionPreprocess + 1721 libobjc.A.dylib 0x00007fff8ecdbe75 objc_exception_throw + 432 CoreFoundation 0x00007fff903e012d -[NSObject(NSObject) doesNotRecognizeSelector:] + 2053 CoreFoundation 0x00007fff9033b044 ___forwarding___ + 4524 CoreFoundation 0x00007fff9033adf8 _CF_forwarding_prep_0 + 1205 a.out 0x0000000108575efd main + 1096 libdyld.dylib 0x00007fff851f35fd start + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException Abort trap: 6
(6) 異常捕獲代碼示例
異常捕獲取示例 : 該示例扔使用上面的 OCAnimal.h, OCCat.h, OCCat.m 示例;
-- OCCatTest.m :?
/*************************************************************************> File Name: OCCatTest.m> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 10/ 5 16:38:01 2015************************************************************************/ #import "OCCat.h"int main(int argc, char * argv[]) {@autoreleasepool {@try{OCCat * cat = [[OCCat alloc] init];[cat run];}@catch (NSException * ex){NSLog(@"exception name : %@, reason : %@", ex.name, ex.reason);}@finally{NSLog(@"finally execute");}NSLog(@"success");} }
-- 執(zhí)行結(jié)果 :?
bogon:6.5 octopus$ clang -fobjc-arc -framework Foundation OCCat.m OCCatTest.m bogon:6.5 octopus$ ./a.out 2015-10-05 16:53:46.850 a.out[3008:507] -[OCCat run]: unrecognized selector sent to instance 0x7f884bc018b0 2015-10-05 16:53:46.853 a.out[3008:507] exception name : NSInvalidArgumentException, reason : -[OCCat run]: unrecognized selector sent to instance 0x7f884bc018b0 2015-10-05 16:53:46.853 a.out[3008:507] finally execute 2015-10-05 16:53:46.854 a.out[3008:507] success
2. 拋出自定義異常
(1) 自定義異常語(yǔ)法
自定義異常拋出 :?
-- 語(yǔ)法 :?
@throw 異常對(duì)象;
(2) 自定義異常代碼示例
自定義異常代碼示例 :?
-- OCException.h 接口 :?
/*************************************************************************> File Name: OCException.h> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 10/ 5 16:58:24 2015************************************************************************/ #import <Foundation/Foundation.h>@interface OCException : NSException @end
-- OCException.m 實(shí)現(xiàn)類 :?
/*************************************************************************> File Name: OCException.m> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 10/ 5 17:03:15 2015************************************************************************/ #import "OCException.h"@implementation OCException @end
-- OCCatTest.m 測(cè)試類 :?
/*************************************************************************> File Name: OCCatTest.m> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 10/ 5 16:38:01 2015************************************************************************/ #import "OCException.h"int main(int argc, char * argv[]) {@autoreleasepool{@throw [[OCException alloc] initWithName : @"OCException" reason : @"this reason is imporant"userInfo : nil];} }
-- 執(zhí)行結(jié)果 :?
bogon:6.5 octopus$ clang -fobjc-arc -framework Foundation OCException.m OCCatTest.m bogon:6.5 octopus$ ./a.out 2015-10-05 17:04:12.432 a.out[3040:507] *** Terminating app due to uncaught exception 'OCException', reason: 'this reason is imporant' *** First throw call stack: (0 CoreFoundation 0x00007fff903dd25c __exceptionPreprocess + 1721 libobjc.A.dylib 0x00007fff8ecdbe75 objc_exception_throw + 432 a.out 0x00000001062abef7 main + 1353 libdyld.dylib 0x00007fff851f35fd start + 1 ) libc++abi.dylib: terminating with uncaught exception of type OCException Abort trap: 6
五. Objective-C 反射
1. 獲取 Class
(1) 程序 與 環(huán)境 交互方式
程序 與 運(yùn)行環(huán)境交互方式 :?
-- 通過(guò) OC 源碼 : 編寫(xiě) OC 源碼, 編譯器編譯, 運(yùn)行在運(yùn)行環(huán)境中;
-- 通過(guò) NSObject 動(dòng)態(tài)編程 : NSObject 是所有類的基類, 所有對(duì)象都可以直接調(diào)用 NSObject 方法;
-- 調(diào)用 運(yùn)行時(shí)函數(shù) 動(dòng)態(tài)編程 : 運(yùn)行時(shí)系統(tǒng)是動(dòng)態(tài)庫(kù), 可以直接調(diào)用這些動(dòng)態(tài)共享庫(kù);
(2) 獲取 Class 方式
獲取 Class 方式 :?
-- 通過(guò)類名 : 使用 "Class NSClassFromString (NSString * aClassName)" 函數(shù)獲取 Class 對(duì)象, 傳入 類名 字符串;
-- class 類方法 : 調(diào)用類方法 class, 調(diào)用方式 [NSString class];
-- class 對(duì)象方法 : 調(diào)用對(duì)象的 class 方法, 調(diào)用方式 [@"hello" class];
-- 推薦使用第二種方式 : 代碼更安全, 編譯階段就可以檢查 Class 是否存在, 程序性能高;
(3) 獲取 Class 代碼示例
代碼示例 :?
/*************************************************************************> File Name: OCGetClass.m> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 10/ 5 23:31:51 2015************************************************************************/#import <Foundation/Foundation.h>int main(int argc, char * argv[]) {@autoreleasepool {//通過(guò) NSClassFromString 方法傳入 類名字符串 獲取 Class 對(duì)象Class clazz = NSClassFromString(@"NSDate");NSLog(@"%@", clazz);id date = [[clazz alloc] init];NSLog(@"date : %@", date);NSString * str = @"hello";// 通過(guò)調(diào)用 類 或 對(duì)象的 class 方法 NSLog(@"[str class] : %@, [NSString class] : %@", [str class], [NSString class]);// 通過(guò)調(diào)用 類 或 對(duì)象的 getter 方法獲取, 即用 . 方法獲取NSLog(@"str.class : %@, NSString.class : %@", str.class, NSString.class);} }
-- 執(zhí)行結(jié)果 :?
bogon:6.6 octopus$ clang -fobjc-arc -framework Foundation OCGetClass.m bogon:6.6 octopus$ ./a.out 2015-10-05 23:39:28.692 a.out[3237:507] NSDate 2015-10-05 23:39:28.699 a.out[3237:507] date : 2015-10-05 15:39:28 +0000 2015-10-05 23:39:28.700 a.out[3237:507] [str class] : __NSCFConstantString, [NSString class] : NSString 2015-10-05 23:39:28.700 a.out[3237:507] str.class : __NSCFConstantString, NSString.class : NSString
2. 檢查繼承關(guān)系
(1) 繼承關(guān)系判斷
繼承關(guān)系判斷方法 :?
-- 判斷類 : isMemberOfClass 方法, 傳入 Class 對(duì)象, 判斷該對(duì)象是否是 Class 對(duì)象對(duì)應(yīng)類的實(shí)例;
-- 判斷類或子類 : isKindOfClass 方法, 傳入 Class 對(duì)象, 判斷該對(duì)象是否是 Class 對(duì)象對(duì)應(yīng)類 或 子類的實(shí)例;
-- 判斷協(xié)議 : conformsToProtocol 犯法, 傳入 Protocol 參數(shù), 傳入方法 "@protocol(協(xié)議名稱)" 或者 ?"Protocol * NSProtocolFromString(NSString * @"協(xié)議名稱")" 兩種方法獲取協(xié)議參數(shù);
(2) 繼承關(guān)系判斷代碼示例
源碼示例 :?
-- OCAnimal.h : 定義協(xié)議;
/*************************************************************************> File Name: OCAnimal.h> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 10/ 5 23:54:14 2015************************************************************************/ #import <Foundation/Foundation.h>@protocol OCAnimal - (void) name; @end
-- OCCat.h : 定義接口;
/*************************************************************************> File Name: OCCat.h> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 10/ 5 23:56:16 2015************************************************************************/ #import "OCAnimal.h"@interface OCCat : NSObject <OCAnimal> @end
-- OCCat.m : 定義實(shí)現(xiàn)類;
/*************************************************************************> File Name: OCCat.m> Author: octopus> Mail: octopus_truth.163.com > Created Time: 一 10/ 5 23:58:47 2015************************************************************************/ #import "OCCat.h"@implementation OCCat - (void) name {NSLog(@"My name is Tom"); } @end
-- OCCatMain.m : 測(cè)試類;
/*************************************************************************> File Name: OCCatMain.m> Author: octopus> Mail: octopus_truth.163.com > Created Time: 二 10/ 6 00:00:01 2015************************************************************************/ #import "OCCat.h"int main(int argc, char * argv[]) {@autoreleasepool {OCCat * cat = [[OCCat alloc] init];NSLog(@"%@", cat.class);NSLog(@"cat isMemberOfClass OCCat : %d", [cat isMemberOfClass : OCCat.class]);NSLog(@"cat isMemberOfClass NSObject : %d", [cat isMemberOfClass : NSObject.class]);NSLog(@"cat isKindOfClass OCCat : %d", [cat isKindOfClass : OCCat.class]);NSLog(@"cat isKindOfClass OCCat : %d", [cat isKindOfClass : NSObject.class]);NSLog(@"cat conformsToProtocol OCAnimal : %d", [cat conformsToProtocol : @protocol(OCAnimal)]);} }
-- 執(zhí)行結(jié)果 :?
bogon:6.6 octopus$ clang -fobjc-arc -framework Foundation OCCat.m OCCatMain.m bogon:6.6 octopus$ ./a.out 2015-10-06 00:07:56.838 a.out[3337:507] OCCat 2015-10-06 00:07:56.840 a.out[3337:507] cat isMemberOfClass OCCat : 1 2015-10-06 00:07:56.840 a.out[3337:507] cat isMemberOfClass NSObject : 0 2015-10-06 00:07:56.841 a.out[3337:507] cat isKindOfClass OCCat : 1 2015-10-06 00:07:56.841 a.out[3337:507] cat isKindOfClass OCCat : 1 2015-10-06 00:07:56.842 a.out[3337:507] cat conformsToProtocol OCAnimal : 1
3. 動(dòng)態(tài)調(diào)用方法
(1) 動(dòng)態(tài)調(diào)用成員變量
KVC 機(jī)制 :?通過(guò)該機(jī)制可以動(dòng)態(tài)調(diào)用對(duì)象的 getter 和 setter 方法, 不論 該變量定義位置 (接口 | 實(shí)現(xiàn)) 和 使用何種訪問(wèn)控制符 (private | public), 都可以使用 KVC 訪問(wèn);
(2) 判斷方法是否可調(diào)用
判斷對(duì)象是否可以調(diào)用方法 :?NSObject 中定義了 respondsToSelector : 方法, 該方法傳入 SEL 參數(shù), 該參數(shù)代表方法, 如果可以調(diào)用 返回 YES, 反之 返回 NO;
獲取 SEL 對(duì)象方法 :?
-- 指令獲取 : 使用 @selector 指令獲取當(dāng)前類中指定的方法, 參數(shù)是 完整的方法簽名關(guān)鍵字, 只有方法名不夠;
@selector(setAge:) withObject
-- 方法獲取 : 使用 SEL NSSelectorFromString(NSString * aSelectorName) 函數(shù), 根據(jù)方法簽名關(guān)鍵字字符串獲取對(duì)應(yīng)方法;
NSSelectorFromString(@"setAge:")
(3) SEL 動(dòng)態(tài)調(diào)用方法
動(dòng)態(tài)調(diào)用對(duì)象方法 :?
-- 動(dòng)態(tài)調(diào)用一 : NSObject 的 performSelector : 方法可以調(diào)用方法, 需要傳入 SEL 對(duì)象, 傳入?yún)?shù) 可以通過(guò) withObject: 標(biāo)簽傳入?yún)?shù);
[student performSelector : @selector(setAge:) withObject : [NSNumber numberWithInt : 18]]; [student performSelector : NSSelectorFromString(@"setAge:") withObject : [NSNumber numberWithInt : 19]];
-- 動(dòng)態(tài)調(diào)用二 : objc_msgSend(receiver, selector, ...) 函數(shù)調(diào)用方法, 參數(shù)一 方法調(diào)用者, 參數(shù)二 調(diào)用的方法, 剩余參數(shù) 方法參數(shù);
objc_msgSend (student, @selector(setAge:), [NSNumber numberWithInt : 20]); objc_msgSend (student, NSSelectorFromString(@"setAge:"), [NSNumber numberWithInt : 21]);
-- 注意 : 使用第二種方法需要導(dǎo)入包 "#import <objc/message.h>", 返回浮點(diǎn)數(shù)時(shí)調(diào)用 objc_msgSend_fpret(), 返回結(jié)構(gòu)體數(shù)據(jù)時(shí) 使用 objc_msgSend_stret() 函數(shù);
(4) IMP 動(dòng)態(tài)調(diào)用方法
IMP 動(dòng)態(tài)調(diào)用方法 簡(jiǎn)介 :?
-- 獲取 IMP 對(duì)象 : NSObject 定義了 "- (IMP) methodForSelector : (SEL) aSelector :" 方法, 該方法傳入 SEL 參數(shù), 返回 IMP 對(duì)象;
-- IMP 作用 : IMP 是 OC 方法函數(shù)指針變量, 代表函數(shù)入口, 通過(guò) IMP 也可以調(diào)用函數(shù);
-- IMP 調(diào)用方法語(yǔ)法 : "返回值類型 (*指針變量) (id, SEL, ...)" , 參數(shù)一 方法調(diào)用者, 參數(shù)二 方法 SEL 對(duì)象, 后面參數(shù)是方法參數(shù);
(5) 動(dòng)態(tài)調(diào)用方法 示例代碼
示例代碼 :?
-- OCStudent.m : 接口實(shí)現(xiàn)類主函數(shù)一體;
/*************************************************************************> File Name: OCStudent.m> Author: octopus> Mail: octopus_truth.163.com > Created Time: 二 10/ 6 11:19:49 2015************************************************************************/ #import <Foundation/Foundation.h> #import <objc/message.h>@interface OCStudent : NSObject @end@implementation OCStudent- (void) setAge : (NSNumber *) age {int age_num = [age intValue];NSLog(@"age is : %d", age_num); } @endint main(int argc, char * argv[]) {@autoreleasepool{OCStudent * student = [[OCStudent alloc] init];[student performSelector : @selector(setAge:) withObject : [NSNumber numberWithInt : 18]];[student performSelector : NSSelectorFromString(@"setAge:") withObject : [NSNumber numberWithInt : 19]];objc_msgSend (student, @selector(setAge:), [NSNumber numberWithInt : 20]);objc_msgSend (student, NSSelectorFromString(@"setAge:"), [NSNumber numberWithInt : 21]);} }
-- 執(zhí)行結(jié)果 : 有報(bào)警;
bogon:6.6 octopus$ clang -fobjc-arc -framework Foundation OCStudent.m OCStudent.m:29:12: warning: performSelector may cause a leak because its selector is unknown [-Warc-performSelector-leaks][student performSelector : NSSelectorFromString(@"setAge:") withObject : [NSNumber numberWithInt : 19]];^ OCStudent.m:29:30: note: used here[student performSelector : NSSelectorFromString(@"setAge:") withObject : [NSNumber numberWithInt : 19]];^ 1 warning generated. bogon:6.6 octopus$ ./a.out 2015-10-06 12:00:41.669 a.out[747:507] age is : 18 2015-10-06 12:00:41.671 a.out[747:507] age is : 19 2015-10-06 12:00:41.671 a.out[747:507] age is : 20 2015-10-06 12:00:41.672 a.out[747:507] age is : 21
總結(jié)
以上是生活随笔為你收集整理的【IOS 开发】Objective - C 面向对象高级特性 - 包装类 | 类处理 | 类别 | 扩展 | 协议 | 委托 | 异常处理 | 反射的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【iOS 开发】Objective -
- 下一篇: 【IOS 开发】Objective-C