學(xué)習(xí)目標(biāo)
1.【了解】異常處理
2.【掌握】類方法
3.【掌握】NSString類
4.【掌握】匿名對(duì)象
5.【掌握】封裝實(shí)例變量
6.【掌握】對(duì)象之間的關(guān)系
一棍鳖、異常處理
什么是異常有咨?
代碼完全符合語(yǔ)法規(guī)范脂新,可以編譯带迟、鏈接颅拦、執(zhí)行丈攒,但是在程序運(yùn)行的時(shí)候承耿,當(dāng)程序處于某種特定情況下的時(shí)候接箫,程序運(yùn)行就會(huì)出錯(cuò)及志,像這樣的情況就叫做程序發(fā)生了異常片排。一旦發(fā)生異常,程序會(huì)立即奔潰速侈。為了避免程序在發(fā)生異常的時(shí)候奔潰率寡,OC提供了@try @catch異常處理。
異常處理語(yǔ)法:
@try {
//可能發(fā)生異常的代碼
}
@catch (NSException *指針名) {
//發(fā)生異常后執(zhí)行的代碼
}
@finally {
//無(wú)論有沒有發(fā)生異常倚搬,都會(huì)執(zhí)行的代碼
}
執(zhí)行步驟:
第一種情況:先執(zhí)行@try中的代碼冶共,如果這里面的代碼發(fā)生了異常,系統(tǒng)就會(huì)把異常信息存儲(chǔ)到@catch中的指針變量,然后執(zhí)行@catch中的代碼捅僵。@catch中的代碼執(zhí)行完畢后家卖,還會(huì)執(zhí)行@finally中的代碼(@finally是可選的)。
第二種情況:先執(zhí)行@try中的代碼庙楚,如果@try中的代碼不發(fā)生異常上荡,@catch中的代碼不會(huì)執(zhí)行。但還是會(huì)執(zhí)行@finally中的代碼(@finally是可選的)馒闷。所以酪捡,@catch中的代碼只有在@try中的代碼發(fā)生異常的時(shí)候才會(huì)執(zhí)行。
注意:
1.@try-@catch只能處理OC中的異常(跟類和對(duì)象有關(guān)的)纳账。
2.寫代碼過(guò)程中盡力使用if來(lái)判斷逛薇,避免異常。
3.@finally不是必須寫的語(yǔ)句疏虫,可以沒有@finally永罚。
二、類方法
OC中的方法分為兩種议薪,對(duì)象方法(實(shí)例方法)和類方法(靜態(tài)方法)尤蛮。
對(duì)象方法:依賴于對(duì)象,對(duì)象方法必須創(chuàng)建對(duì)象斯议,通過(guò)對(duì)象名來(lái)調(diào)用产捞。
類方法:不依賴與對(duì)象,類方法不需要?jiǎng)?chuàng)建對(duì)象哼御,通過(guò)類名來(lái)調(diào)用坯临。
聲明語(yǔ)法:+ (返回值類型)方法名;
//聲明類方法
@interface Person : NSObject
+ (void)test;
@end
//實(shí)現(xiàn)類方法
@implementation Person
+ (void)test{
NSLog(@"this is a class method!");
}
@end
//主函數(shù)里調(diào)用類方法
[Person test];
注意:
1.對(duì)象方法和類方法的方法名可以同名,兩個(gè)方法互不影響恋昼。
2.類方法調(diào)用不需要?jiǎng)?chuàng)建對(duì)象看靠,從效率上而言會(huì)更快一些。
3.對(duì)象方法只能通過(guò)對(duì)象名來(lái)調(diào)用液肌,類方法只能通過(guò)類名來(lái)調(diào)用挟炬。
4.對(duì)象方法中可以直接訪問(wèn)實(shí)例變量和類方法,類方法中不能直接訪問(wèn)實(shí)例變量和對(duì)象方法嗦哆。
5.如果方法不需要訪問(wèn)對(duì)象的實(shí)例變量的時(shí)候谤祖,我們可以將其定義為類方法,提高效率老速。
類方法的規(guī)范
提供一個(gè)和類同名的類方法來(lái)創(chuàng)建一個(gè)對(duì)象粥喜。比如:
+ (Person *)person;//聲明類方法
//實(shí)現(xiàn)類方法
+ (Person *)person{
Person *person = [Person new];//創(chuàng)建對(duì)象person
return person;//返回對(duì)象person
}
提供一個(gè)類方法創(chuàng)建對(duì)象,并讓調(diào)用者可以初始化新創(chuàng)建對(duì)象的實(shí)例變量的值橘券。比如:
+ (Person *)personWithName:(NSString *)name;//聲明類方法
//實(shí)現(xiàn)類方法
+ (Person *)personWithName:(NSString *)name{
Person *person = [Person new];//創(chuàng)建對(duì)象person
person -> _name = name;//將調(diào)用者傳遞進(jìn)來(lái)的參數(shù)賦值給person對(duì)象的實(shí)例變量
return person;//返回對(duì)象person
}
三额湘、NSString類
OC中提供了一個(gè)字符串類NSString卿吐,以對(duì)象的形式存儲(chǔ)字符串。
NSString類的常用方法
//stringWithCString:將C語(yǔ)言字符串轉(zhuǎn)化為OC字符串锋华。
NSString *str = [NSString stringWithCString:"C字符串"];
//stringWithFormat:格式化字符串嗡官,也可以做多個(gè)變量、字符串的拼接供置。
for(int i = 1;i <= 1000;i++){
NSString *str = [NSString stringWithFormat:@"d",i];
NSLog(@"%@",str);
}
//length計(jì)算字符串長(zhǎng)度谨湘,是計(jì)算字符個(gè)數(shù),一個(gè)中文字也是1個(gè)長(zhǎng)度。
NSString *str = @"字符串a(chǎn)bcd";
NSUInteger length = [str length];//這里是長(zhǎng)度為7
//characterAtIndex:獲取指定位置的字符芥丧,位置從0開始遞增。
NSString *str = @"字符串a(chǎn)bcd";
unichar ch = [str characterAtIndex:3];//從0開始計(jì)算
NSLog(@"ch = %C",ch); //%C OC里新增的格式控符,可以輸出單個(gè)中文
//isEqualToString:比較兩個(gè)字符串是否相同坊罢。
NSString *str = @"字符串a(chǎn)bcd";
NSString *str1 = @"字符串a(chǎn)bcd";
BOOL res = [str isEqualToString:str1];
//compare:比較兩個(gè)字符串的大小(ASCII)
NSString *s1 = @"China";
NSString *s2 = @"Japan";
int res = [s1 compare:s2];
NSLog(@"res = %i",res);//s1 < s2則返回1? s1 > s2 返回-1 相等返回0
四续担、匿名對(duì)象
實(shí)例化一個(gè)對(duì)象的時(shí)候,沒有用任何指針指向這個(gè)對(duì)象活孩,這個(gè)對(duì)象就是匿名對(duì)象物遇。并且匿名對(duì)象只能調(diào)用一次,所以如果你只是為了調(diào)用某一個(gè)對(duì)象的對(duì)象方法憾儒,就可以使用匿名對(duì)象询兴。比如:
//Person.h文件
#import
@interface Person : NSObject
{
NSString *_name;
}
- (void)sayHi;
@end
//Person.m文件
#import "Person.h"
@implementation Person
- (void)sayHi{
NSLog(@"這是對(duì)象方法");
}
@end
//main.m文件
#import
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//給匿名對(duì)象的實(shí)例變量賦值,不過(guò)匿名對(duì)象只能訪問(wèn)一次,賦值后就不能再使用了
[Person new] -> name = @"jack";
//調(diào)用匿名對(duì)象的對(duì)象方法,調(diào)用完了就不再用這個(gè)對(duì)象了
[[Person new] sayHi];
}
return 0;
}
五、封裝實(shí)例變量
一個(gè)類之中有多個(gè)屬性起趾、方法诗舰,把這些成員封裝在一個(gè)類中,把這個(gè)類當(dāng)做一個(gè)整體來(lái)使用训裆。
封裝的好處:便于管理代碼的維護(hù)眶根,以類為單位來(lái)管理他們。屏蔽內(nèi)部的實(shí)現(xiàn)边琉,對(duì)于外部而言只是一個(gè)對(duì)象属百。
為對(duì)象的屬性賦值的時(shí)候,只要賦值的數(shù)據(jù)的類型和屬性的類型一致就可以了变姨。但是族扰,這樣的賦值往往都不能隨意賦值。比如人的年齡為int類型定欧,我們賦值-10語(yǔ)法也不會(huì)報(bào)錯(cuò)渔呵。但這種賦值不符合實(shí)際情況,所以我們要為屬性賦值范圍加以限定忧额。
首先厘肮,實(shí)例變量一定不能被@public修飾,因?yàn)橐坏┍籃public修飾睦番,就能在外界通過(guò)對(duì)象名來(lái)訪問(wèn)這個(gè)實(shí)例變量类茂,隨意修改實(shí)例變量的值耍属。然后給實(shí)例變量提供兩種方法來(lái)供外界為實(shí)例變量賦值和訪問(wèn),也就是setter和getter方法巩检。只有g(shù)etter方法沒有setter方法叫只讀封裝厚骗,只有setter方法沒有g(shù)etter方法叫只寫封裝。
為類提供一種專門為實(shí)例變量賦值的方法 setter
1.這個(gè)方法一定是一個(gè)對(duì)象方法兢哭,因?yàn)橹挥袑?duì)象方法才能直接訪問(wèn)實(shí)例變量领舰。
2.這個(gè)方法一定沒有返回值,為實(shí)例變量賦值不需要返回值迟螺。
3.這個(gè)方法一定是有參數(shù)的冲秽,為實(shí)例變量賦值一定需要傳入一個(gè)和實(shí)例變量類型相同的參數(shù)。
4.這個(gè)方法的方法名以set開頭矩父,后面跟實(shí)例變量名去掉下劃線锉桑,并首字母大寫。
為類提供一種專門訪問(wèn)實(shí)例變量的值的方法 getter
1.這個(gè)方法一定是一個(gè)對(duì)象方法窍株,因?yàn)橹挥袑?duì)象方法才能直接訪問(wèn)實(shí)例變量民轴。
2.這個(gè)方法一定有返回值,供外界訪問(wèn)實(shí)例變量球订,必須要返回給調(diào)用者實(shí)例變量的值后裸。
3.這個(gè)方法一定沒有參數(shù),訪問(wèn)實(shí)例變量的值不需要傳入任何參數(shù)冒滩。
4.這個(gè)方法的方法名就是去掉下劃線的實(shí)例變量的名字微驶。
//Person.h文件
#import
@interface Person : NSObject
{
//不要給實(shí)例變量@public修飾
int _age;
}
//setter聲明
- (void)setAge:(int)age;
//getter聲明
- (int)age;
@end
//Person.m文件
#import "Person.h"
@implementation Person
//setter實(shí)現(xiàn)
- (void)setAge:(int)age{
//傳入的年齡在 0 - 120之間才能賦值,否則輸出提示
if(age > 0 && age < 120){
_age = age;
}else{
NSLog(@"年齡不符合");
}
}
//getter實(shí)現(xiàn)
- (int)age{
return _age;
}
@end
//main.m文件
#import
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
//實(shí)例化一個(gè)對(duì)象p
Person *p = [Person new];
//調(diào)用p對(duì)象setAge方法為對(duì)象的實(shí)例變量賦值
[p setAge:200];//因?yàn)椴环弦?guī)范,會(huì)打印出 年齡不符合
//輸出p對(duì)象的實(shí)例變量age的值
NSLog(@"age = %i",[p age]);//輸出 age = 0
}
return 0;
}
注意:
1.setter和getter方法的命名必須符合規(guī)范旦部。
2.實(shí)例變量無(wú)論如何都不能用@public修飾,不然就不符合封裝的理念祈搜。
3.只要實(shí)例變量要被外界訪問(wèn),都應(yīng)該為他封裝一個(gè)setter和getter方法士八。
六容燕、對(duì)象之間的關(guān)系
組合關(guān)系
一個(gè)類是由多個(gè)對(duì)象組合而成的(多個(gè)對(duì)象都是同一個(gè)類的實(shí)例變量),那么他們之間的關(guān)系就叫組合關(guān)系婚度。
依賴關(guān)系
一個(gè)方法的參數(shù)是另一個(gè)對(duì)象(依賴參數(shù)那個(gè)對(duì)象,沒有了參數(shù)就無(wú)法整了)蘸秘,那么他們之間的關(guān)系就是依賴關(guān)系。
關(guān)聯(lián)關(guān)系
當(dāng)一個(gè)對(duì)象擁有另外一個(gè)對(duì)象的時(shí)候(一個(gè)對(duì)象是另一個(gè)對(duì)象的實(shí)例變量蝗茁,但是他們并不是組合關(guān)系)醋虏,那么他們之間的關(guān)系就是關(guān)聯(lián)關(guān)系。
面向?qū)ο笤O(shè)計(jì)中:
耦合度? 當(dāng)修改一個(gè)對(duì)象的時(shí)候,對(duì)另外一個(gè)對(duì)象的影響程度
低耦合? 當(dāng)修改一個(gè)對(duì)象的對(duì)其他對(duì)象影響比較小
高內(nèi)聚? 一個(gè)對(duì)象僅僅做自己相關(guān)的事情
面向?qū)ο笤O(shè)計(jì)原則是高內(nèi)聚哮翘、低耦合颈嚼,單一職責(zé)原則。