我的盲區(qū)不一定是你的盲區(qū)盐数,歡迎copy。
但是閑下來不要忘記還有很多你了解不夠透徹的滨达。
點(diǎn)語法的死循環(huán)注意
在set方法和get方法別用點(diǎn)語法得滤,否則會(huì)產(chǎn)生死循環(huán)陨献。以下兩個(gè)方法會(huì)產(chǎn)生死循環(huán)
- (void)setAge:(int)age{
self.age = age;
//展開成:[self setAge:age];
}
- (int)age{
return self.age;
//展開成:return [self age];
}
SEL的概念
在Objective-C中,SEL是選擇器(selector)的一個(gè)類型耿戚。選擇器就是指向方法的一個(gè)指針湿故。
可以簡單理解成:SEL其實(shí)是對(duì)方法的一種包裝,將方法包裝成一個(gè)SEL類型的數(shù)據(jù)膜蛔。去找對(duì)應(yīng)的方法地址坛猪。找到方法地址就可以調(diào)用方法。
調(diào)用
//Person類中有 +test1方法和 -test2方法
Person *p = [Person new];
//調(diào)用對(duì)象方法 -test2 方法1
[p test2]
//方法2:利用sel間接調(diào)用
[p performSelector:@selector(test2)];
若調(diào)用的方法需要傳參數(shù)
[p test3:@"chenfanfang"];
//或者用sel方法
[p performSelector:@selector(test3:)withObject:@"chenfanfang"];
//注意:方法若有參數(shù)皂股,則寫方法名不能漏了冒號(hào):
創(chuàng)建SEL類型的數(shù)據(jù)
SEL s = @selector(test3);
copy墅茉,retain,assign的區(qū)別
retain :release舊值呜呐,retain新值(適用oc對(duì)象類型)就斤。retain屬性表示兩個(gè)對(duì)象地址相同(建立一個(gè)指針,指針拷貝)蘑辑,內(nèi)容當(dāng)然相同洋机,這個(gè)對(duì)象的引用計(jì)數(shù)+1(引用計(jì)數(shù)變?yōu)?)。
assign :默認(rèn)屬性 直接賦值洋魂,不改變引用計(jì)數(shù)(retainCount)绷旗,適用于非oc對(duì)象類型,用于基礎(chǔ)數(shù)據(jù)類型 (NSInteger)和C數(shù)據(jù)類型(int,float, double, char,等)副砍,其中int這樣的基本類型并不是對(duì)象衔肢,如果使用retain與copy會(huì)報(bào)錯(cuò)。
copy :release舊值豁翎,copy新值角骤。copy是創(chuàng)建一個(gè)新對(duì)象,而retain是創(chuàng)建一個(gè)指針使對(duì)象引用計(jì)數(shù)加1心剥。Copy屬性表示兩個(gè)對(duì)象內(nèi)容相同邦尊,新的對(duì)象引用計(jì)數(shù)為1 ,與舊有對(duì)象的引用計(jì)數(shù)無關(guān)优烧,舊有對(duì)象沒有變化蝉揍。copy減少對(duì)象對(duì)上下文的依賴。(如果牽扯到上面程序中兩個(gè)值互相影響的情況匙隔,應(yīng)該用copy)
總結(jié)一下疑苫,retain 是指針拷貝,copy 是內(nèi)容拷貝纷责。
基本的數(shù)據(jù)類型
id類型:類似Java 的Object 類捍掺,可以轉(zhuǎn)換為任何數(shù)據(jù)類型,id類型已經(jīng)是指針了再膳,所以變量不需要加*
id foo=nil挺勿;
atomic,nonatomic readonly,readwrite
atomic是默認(rèn)屬性,保證setter/getter的原子性喂柒,即線程同步不瓶。nonatomic不保證原子性
readwrite為默認(rèn)屬性,生成默認(rèn)的setter/getter方法灾杰。readonly只生成getter方法蚊丐。
權(quán)限問題
private(自己):該類中的方法可以訪問這樣的變量,但不能被子類定義的方法直接訪問艳吠。
protected(自己與子類):該類和任何的子類中的方法可以直接訪問這樣的變量麦备,這是默認(rèn)的。
public(自己昭娩,子類凛篙,其他類):除了自己和子類中的方法外,也可以被其他類或者其他模塊中的方法所訪問栏渺。開放性最大呛梆,但最好避免使用這個(gè)作用域。其他類應(yīng)該使用getter/setter方法來訪問或設(shè)置其他類上的實(shí)例變量磕诊,確保封裝性填物。
package:
注:默認(rèn)的變量權(quán)限為protected,方法只能為public
內(nèi)存管理
概念
1.oc使用“引用計(jì)數(shù)(retainCount)”方式來管理內(nèi)存秀仲。當(dāng)該對(duì)象創(chuàng)建時(shí)融痛,該計(jì)數(shù)為1,說明有一個(gè)引用神僵,如果不用時(shí)雁刷,就會(huì)減為0,這就表示不再使用了保礼,那么就會(huì)銷毀該空間沛励。
方法:
1.alloc, allocWithZone,new(帶初始化)
為對(duì)象分配內(nèi)存,retainCount為“1”炮障,并返回此實(shí)例目派。
2.retain
retainCount 加“1”
3.copy,mutableCopy
復(fù)制一個(gè)實(shí)例,retainCount數(shù)為“1”胁赢,返回此實(shí)例企蹭。所得到的對(duì)象是與其它上下文無關(guān)的,獨(dú)立的對(duì)象(干凈對(duì)象)。
4.release
retainCount 減“1”谅摄,減到“0”時(shí)調(diào)用此對(duì)象的dealloc方法
5.autorelease
把當(dāng)前對(duì)象放入了當(dāng)前的Autoreleasepool中徒河,當(dāng)該pool被釋放時(shí),該pool中的所有Object會(huì)被調(diào)用Release
我們可以把上面的接口按對(duì)retainCount的操作性質(zhì)歸為兩類送漠,
A類是加一操作:1顽照,2,3
B類是減一操作:4闽寡,5(延時(shí)釋放)
內(nèi)存管理準(zhǔn)則如下:
1代兵,A與B類的調(diào)用次數(shù)保持一制
2,為了很好的保障準(zhǔn)則一爷狈,以實(shí)例對(duì)象為單位植影,誰A了就誰B,沒有第二者參與
內(nèi)存管理ARC
概念:
- 從XCode4.2開始就引入Automatic Reference Counting機(jī)制涎永。我們創(chuàng)建的模板能看到@autoreleasepool{};
- ARC使得你不需要再思考何時(shí)使用retain,release,autorelease這樣的函數(shù)來管理內(nèi)存何乎,它提供了自動(dòng)評(píng)估內(nèi)存生存期的功能,并且在編譯期間自動(dòng)加入合適的管理內(nèi)存的方法土辩。編譯器也會(huì)自動(dòng)生成dealloc函數(shù)支救。
基本的ARC使用規(guī)則:
1.代碼中不能使用 release, retain, autorelease,dealloc, retainCount
2.不重載dealloc(如果是釋放對(duì)象內(nèi)存以外的處理,是可以重載該函數(shù)的拷淘,但是不能調(diào)用[super dealloc])
3.不能使用NSAllocateObject, NSDeallocateObject
4.不能在C結(jié)構(gòu)體中使用對(duì)象指針
5.id與void *間的如果cast時(shí)需要用特定的方法(__bridge關(guān)鍵字)
6.不能使用NSAutoReleasePool各墨、而需要@autoreleasepool塊
7.不能使用“new”開始的屬性名稱
property 內(nèi)存管理策略的選擇
1、非ARC下
①copy:只用于NSString启涯、block
②retain:除NSString贬堵、block以外的OC對(duì)象
③assign:基本數(shù)據(jù)類型、枚舉结洼、結(jié)構(gòu)體(非OC對(duì)象)黎做、當(dāng)兩個(gè)對(duì)象相互引用時(shí),一端用retain松忍,一端用assign
2蒸殿、ARC下
①copy:只用于NSString、block
②strong:除NSString鸣峭、block以外的OC對(duì)象
③weak:當(dāng)兩個(gè)對(duì)象相互引用宏所,一端用strong,一端用weak
④assign:基本數(shù)據(jù)類型摊溶、枚舉爬骤、結(jié)構(gòu)體(非OC對(duì)象)
字典類型 NSDictionary 和 NSMutableDictionary
概念
1.字典類型 NSDictionary 和 數(shù)組NSArray 類型相似,但存在數(shù)組里要取值每次都要遍歷莫换,這樣就浪費(fèi)了很長的時(shí)間霞玄,字典的便利就在于他在存取對(duì)象的時(shí)候骤铃,在后面會(huì)追加一個(gè) 鍵值,可以理解成一個(gè)標(biāo)志坷剧,我們可以根據(jù)這個(gè)標(biāo)志很快的找到這個(gè)對(duì)象劲厌,這樣就相對(duì)于數(shù)組的全部遍歷就要方便多。
2.字典類型與數(shù)組類型相似听隐,都是存取的對(duì)象,不能存取基本的數(shù)據(jù)類型哄啄,如 int , double, char等雅任,類比數(shù)組,字典自然也會(huì)有兩種類型咨跌,不可變字典: NSDictionary 和 可變字典 NSMutableDictionary
3.字典中的數(shù)據(jù)是以 鍵值對(duì) 的形式出現(xiàn)沪么,并且順序不能亂,前邊是對(duì)象锌半,后面是鍵名
NSDictionary
創(chuàng)建:
1.NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:student1,@"小明",student2,@"小剛",student3,@"小紅",nil];
2.NSDictionary * dic = @{student1:@"小明",student2:@"小剛",student3:@"小紅"};
使用
NSArray *arrayA =[NSArrayarrayWithObjects:@"B",@"A",@"E",@"D",@"C", nil];
NSDictionary *dic1 = [[NSDictionary alloc] initWithObjectsAndKeys:arrayA,@"name",@"1234",@"tel",nil];
//全部的key 這個(gè)結(jié)果的順序不是固定的禽车,因?yàn)椴檎业姆椒楣2檎遥詳?shù)組的順序有可能不是你所定義的順序
NSArray *keysAll = [dic1 allKeys];
//全部的value 這個(gè)結(jié)果的順序也不是固定的
NSArray *valuesAll = [dic1 allValues];
//取出值為Yue的所有key值
NSArray *key = [dic1 allKeysForObject:arrayA];
//取出key值為name的對(duì)象(萬物皆對(duì)象)
NSArray *value = [dic1 objectForKey:@"name"];
NSMutableDictionary
創(chuàng)建:
NSArray *arrayA = [NSArray arrayWithObjects:@"B",@"A",@"E",@"D",@"C", nil];
NSArray *arrayB = [NSArray arrayWithObjects:@"1",@"2",@"3",@"4", nil];
NSMutableDictionary *dic2 = [NSMutableDictionary dictionaryWithObjectsAndKeys:arrayA,@"hong",@"stu2",@"huang",nil];
使用:
//刪除key值為huang的value值 連同key一起刪
[dic2 removeObjectForKey:@"huang"];
//刪除全部
[dic2 removeAllObjects];
//添加key值為book的value:arrayB
[dic2 setObject:arrayB forKey:@"book"];
NSArray
創(chuàng)建:
NSArray *arrayA = [NSArrayarrayWithObjects:@"B",@"A",@"E",@"D",@"C", nil];
NSArray *arrayB = [NSArray arrayWithObjects:@"1",@"2",@"3",@"4", nil];
NSLog(@"arrayA:%@,arrayB%@",arrayA,arrayB);
//1刊殉、獲取數(shù)組中總共有多少個(gè)對(duì)象殉摔。
NSLog(@"個(gè)數(shù):%lu",(unsigned long)arrayA.count);
NSLog(@"個(gè)數(shù):%lu",(unsigned long)[arrayB count]);
//2、獲取數(shù)組中下標(biāo)對(duì)應(yīng)的元素對(duì)象.(下標(biāo)是從0開始)
NSLog(@"獲取下標(biāo)為1的元素:%@" ,[arrayA objectAtIndex:1]);
//3记焊、在當(dāng)前數(shù)據(jù)中追加一個(gè)新的對(duì)象逸月,并且返回一個(gè)新的數(shù)據(jù)對(duì)象(新的數(shù)組對(duì)象和被追加的對(duì)象,是兩個(gè)不同的數(shù)組對(duì)象)遍膜。
NSLog(@"重組數(shù)組 組成新數(shù)組:%@" ,[arrayA arrayByAddingObject:@"F"]);
//4碗硬、在當(dāng)前的數(shù)組中追加一個(gè)新的數(shù)據(jù),并且返回一個(gè)新的數(shù)組對(duì)象瓢颅。
NSLog(@"2個(gè)數(shù)組重組組成新數(shù)組:%@",[arrayA arrayByAddingObjectsFromArray:arrayB]);
//5恩尾、使用當(dāng)前的數(shù)組生成一個(gè)字符串,新生成的字符串使用提供的separator字符進(jìn)行分割挽懦。
NSLog(@"分割成字符串%@",[arrayA componentsJoinedByString:@","]);
//6翰意、檢測(cè)數(shù)據(jù)中是否包含指定的對(duì)象元素
NSLog(@"arrayA是否有1:%i,arrayA是否有A:%i",[arrayA containsObject:@"1"],[arrayA containsObject:@"A"]);
//7信柿、使用當(dāng)前的數(shù)組生成字符串猎物。允許一個(gè)對(duì)象返回一個(gè)字符串來描述它的內(nèi)容;這個(gè)常用于調(diào)試debugging
NSLog(@"重寫改變生成字符串:%@",[arrayA description]);
// 8角塑、根據(jù)設(shè)置的locale 進(jìn)行連接數(shù)組
// NSLog(@"連接數(shù)組1:%@",[arrayA descriptionWithLocale:@"4"]);
// NSLog(@"連接數(shù)組2:%@",[arrayA descriptionWithLocale:arrayB indent:1]);
//9蔫磨、兩個(gè)數(shù)組的第一個(gè)元素是否相同,如果相同圃伶,則返回 數(shù)組中堤如,第一個(gè)元素的字符串蒲列,反之,返回null 對(duì)象
NSLog(@"兩個(gè)數(shù)組的第一個(gè)元素是否相同:%@",[arrayA firstObjectCommonWithArray:arrayB]);
//10搀罢、 從數(shù)組中獲取NSRange對(duì)象的數(shù)據(jù)存放到objects 中蝗岖,NSRange的數(shù)據(jù)標(biāo)示從location,開始后面length 個(gè)數(shù)據(jù)
//-(void)getObjects:(id__unsafe_unretained [])objects range:(NSRange)range;
//11、 判斷制定的anObject 對(duì)象是否存在數(shù)組中如果存在返回榔至,對(duì)象所在的下標(biāo)
NSUInteger index= [arrayA indexOfObject:@"C"];
if (index == NSNotFound) {
NSLog(@"不在");
}else{
NSLog(@"對(duì)象所在的下標(biāo):%lu",index);
}
//11-1抵赢、 判斷制定的元素,是否在數(shù)組中唧取,數(shù)組查詢的位置铅鲤,是從range.location 的位置開始,到range.length 的長度結(jié)束
NSUInteger index1= [arrayA indexOfObject:@"C" inRange:NSMakeRange(0, 2)];
if (index1 == NSNotFound) {
NSLog(@"不在");
}else{
NSLog(@"對(duì)象所在的下標(biāo)1:%lu",index1);
}
//12枫弟、比較兩個(gè)數(shù)組是否相同 邢享,數(shù)組長度相同,并且相同位置上的元素也相同淡诗。
NSLog(@"兩個(gè)數(shù)組是否相同:%i",[arrayA isEqualToArray:arrayB]);
//13骇塘、返回最有一個(gè)元素,如果一個(gè)數(shù)組的長度為0 返回的對(duì)象為nil
NSLog(@"arrayA最后一個(gè):%@,arrayA第一個(gè):%@",[arrayA lastObject],[arrayA firstObject]);
// 15韩容、使用數(shù)組返回一個(gè) NSEnumerator 對(duì)象款违,這個(gè)對(duì)象類似與一個(gè)指針,可以用來遍歷 整個(gè)數(shù)組 指針從前向后遍歷
// NSEnumerator *enu = [arrayA objectEnumerator];
// NSLog(@"enu:%@",enu);
//這是用來排序的函數(shù)群凶,comparator 這個(gè)參數(shù)奠货,需要傳入一個(gè)返回結(jié)果是NSComparisonResult 的函數(shù),
NSArray *a = [arrayA sortedArrayUsingSelector:@selector(compare:)];
NSArray *b = [arrayA sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
NSArray *c = [arrayA sortedArrayUsingSelector:@selector(localizedCompare:)];
NSLog(@"aaaa:%@,bbbb:%@,cccc:%@",a,b,c);
//21座掘、用來獲取數(shù)組中range.location 開始递惋,數(shù)據(jù)各數(shù) 為range.length 的數(shù)據(jù),并放置到一個(gè)新的數(shù)組中
NSLog(@"arrayA第1個(gè)起后2個(gè)數(shù)%@",[arrayA subarrayWithRange:NSMakeRange(1, 2)]);
//22溢陪、寫入數(shù)組中的數(shù)據(jù)萍虽,到指定path 的目錄中:
BOOL q = [arrayA writeToFile:@"path" atomically:YES];
NSLog(@"%i",q);
//23、如同上面的方法一樣形真,所不同的是寫入數(shù)組中的內(nèi)容到 網(wǎng)上指定的路徑杉编。
BOOL q1 = [arrayA writeToURL:[NSURL URLWithString:@"網(wǎng)上的路徑"] atomically:YES];
NSLog(@"%i",q1);
//26、 用來根據(jù)indexes 獲取一個(gè)數(shù)組咆霜, NSIndexSet 是一個(gè)用來管理 index 的對(duì)象邓馒。
NSLog(@"arrayA第一個(gè):%@",[arrayA objectAtIndex:1]);
NSIndexSet *se = [NSIndexSet indexSetWithIndex:2];
NSIndexSet *se1 = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(1, 3)];
NSArray *test = [arrayA objectsAtIndexes:se];
NSArray *test1 = [arrayA objectsAtIndexes:se1];
NSLog(@"se:%@,se1:%@,test:%@,test1:%@",se,se1,test,test1);
//27、返回指定下標(biāo)的一個(gè)對(duì)象蛾坯。這個(gè)方法類似 objectAtIndex:
NSLog(@"arrayA第4個(gè):%@",[arrayA objectAtIndexedSubscript:4]);
//28光酣、使用block 塊遍歷整個(gè)數(shù)組。這個(gè)block 需要三個(gè)參數(shù)脉课,id obj 表示數(shù)組中的元素救军。
//NSUInteger idx 標(biāo)示元素的下標(biāo)财异,
//bool *stop 是一個(gè)bool類型的參數(shù)
[arrayA enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSLog(@"%@,%lu",obj,(unsigned long)idx);
}];
//Options:遍歷方向 反向
[arrayA enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSLog(@"%@,%lu",obj,(unsigned long)idx);
}];
//30、 同上面的方法一項(xiàng)唱遭,不過NSIndexSet 參數(shù)標(biāo)示戳寸,根據(jù)下標(biāo)取出的數(shù)組,這里真正在block 中遍歷的數(shù)組拷泽,是根據(jù)NSindexSet 取到的子數(shù)組 w
[arrayB enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(1, 3)] options:NSEnumerationConcurrent usingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
NSLog(@"%@,%lu",obj,(unsigned long)idx);
}];
//31疫鹊、 根據(jù)條件用來獲取一個(gè)NSUIndex 對(duì)象,主要是根據(jù)條件進(jìn)行數(shù)據(jù)遍歷使用
NSInteger index11 = [arrayA indexOfObjectPassingTest:^BOOL(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([@"A" isEqualToString:obj]) {
NSLog(@"YESSSSS");
return YES;
}else{
NSLog(@"NOOOOO");
return NO;
}
}];
NSLog(@"index11:%ld",(long)index11);
//33 司致、 這個(gè)方法添加了參數(shù)拆吆,用來表示,是從前向后蚌吸,遍歷還是從后向前遍歷 執(zhí)行了arrayA.count次
NSInteger index12 = [arrayA indexOfObjectWithOptions:NSEnumerationReverse passingTest:^BOOL(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if ([@"1" isEqualToString:obj]) {
NSLog(@"YES");
return YES;
}else{
NSLog(@"NOO");
return NO;
}
}];
NSLog(@"index12:%ld",(long)index12);
NSIndexSet *index33 = [arrayA indexesOfObjectsWithOptions:NSEnumerationReverse passingTest: ^ BOOL (id tr, NSUInteger index,BOOL *te){
if([tr isEqualToString:@"E"]){
return YES;
}
return NO;
}];
NSLog(@"index33:%@",index33);
//35、對(duì)數(shù)組進(jìn)行排序操作 參數(shù)cmptr 是一個(gè)block 函數(shù)塊砌庄,返回的數(shù)據(jù)類型是一個(gè)NSComparisonResult 對(duì)象
NSArray *comparator = [arrayA sortedArrayUsingComparator:^NSComparisonResult(NSString *s1, NSString *s2) {
//characterAtIndex:獲取指定位置的字符羹唠,位置從0開始遞增。
if ([s1 characterAtIndex:0] < [s2 characterAtIndex:0]) {
return NSOrderedAscending;
}else if ([s1 characterAtIndex:0] > [s2 characterAtIndex:0]){
return NSOrderedDescending;
}else{
return NSOrderedSame;
}
}];
NSLog(@"comparator:%@",comparator);
//36娄昆、進(jìn)行排序操作佩微,NSSortOptions 排序的參數(shù) 用來表示是同時(shí)排序,還是穩(wěn)定執(zhí)行萌焰。
NSArray *test111 = [arrayA sortedArrayWithOptions:NSSortStable usingComparator:^ NSComparisonResult (NSString *s,NSString *s2){
//s.length 表示s的長度 一個(gè)中文也算1
if(s.length < s2.length){
return NSOrderedAscending;
}
if(s.length > s2.length){
return NSOrderedDescending;
}
return NSOrderedSame;
}];
NSLog(@"test111:%@",test111);
基礎(chǔ)框架類
NSData:序列字節(jié)哺眯,不可修改。要修改的話需要用到NSData子類NSMutableData扒俯。NSData主要用于從網(wǎng)上下載數(shù)據(jù)(以NSData對(duì)象返回?cái)?shù)據(jù))奶卓;把對(duì)象存儲(chǔ)在文件中;讀取文件數(shù)據(jù)(將NSData對(duì)象當(dāng)做緩存區(qū))撼玄。
NSSet:無序的不同對(duì)象的集合夺姑,不可變,可通過調(diào)用方法增加或刪除一個(gè)集合來獲得新的NSSet對(duì)象掌猛。它的子類是NSMutableSet盏浙。
NSDictionary:其鍵值對(duì)的無序集合,鍵通常是NSString荔茬,值可以是任何一個(gè)對(duì)象废膘,NSDictionary是定長的,它的變長子類是NSMutableDictionary慕蔚。
屬性列表
NSObject:每個(gè)類都是從NSObject繼承來的,它采用 NSObject協(xié)議丐黄,它實(shí)現(xiàn)了與 NSCopying、 NSMutableCopying和 NSCoding 協(xié)議相關(guān)的方法孔飒,
繼承孵稽,重寫覆蓋许起,重載
方法重寫:若子類中的方法與父類的某一方法具有相同的方法名、返回類型和參數(shù)表菩鲜,則新方法覆蓋原有方法园细。
方法重載:類中可以創(chuàng)建多個(gè)方法,他們具有相同的方法名接校,但具有不同的參數(shù)和不同的定義猛频,調(diào)用方法時(shí)通過傳遞給他們不同個(gè)數(shù)和類型的參數(shù)來決定使用哪個(gè)方法。 方法名一定相同蛛勉;方法的參數(shù)表必須不同鹿寻,包括參數(shù)的個(gè)數(shù)和類型,以此區(qū)分不同的方法體诽凌; 方法的返回類型和修飾符可以相同也可以不同毡熏。
self:一個(gè)類中的方法調(diào)用同一個(gè)類的另一個(gè)方法是使用self,代表本身侣诵,相當(dāng)于this痢法。
super:表示父類,可以使用super訪問父類中被子類隱藏或重寫的方法杜顺。
1.oc中只能單繼承财搁,即一個(gè)類只有一個(gè)父類
2.子類可以重寫父類的方法,對(duì)其進(jìn)行覆蓋躬络。
子類內(nèi)部還能調(diào)用父類的該方法尖奔,使用super
[super method];
3.oc不支持重載,即使參數(shù)不一樣也不能使用同名方法
異常處理語法:
@try {
//可能發(fā)生異常的代碼
}
@catch (NSException *指針名) {
//發(fā)生異常后執(zhí)行的代碼
}
@finally {
//無論有沒有發(fā)生異常穷当,都會(huì)執(zhí)行的代碼
}
對(duì)象與類
1.對(duì)象方法和類方法的方法名可以同名提茁,兩個(gè)方法互不影響。
2.類方法調(diào)用不需要?jiǎng)?chuàng)建對(duì)象馁菜,從效率上而言會(huì)更快一些甘凭。
3.對(duì)象方法只能通過對(duì)象名來調(diào)用,類方法只能通過類名來調(diào)用火邓。
面向?qū)ο笤O(shè)計(jì)原則
1.耦合度 當(dāng)修改一個(gè)對(duì)象的時(shí)候,對(duì)另外一個(gè)對(duì)象的影響程度
2.高內(nèi)聚 一個(gè)對(duì)象僅僅做自己相關(guān)的事情
注:面向?qū)ο笤O(shè)計(jì)原則是高內(nèi)聚丹弱、低耦合
NSString
拼接,合并铲咨,轉(zhuǎn)換
//經(jīng)典的字符串賦值
NSString *str0 = @"my name is justcoding !";
//字符串格式化合并分別包括
//NSString*類型 int類型 char*類型
NSString *str1 = [NSString stringWithFormat:@"我的名字:%@ 我的年齡:%d 我的郵箱:%s",@"justcoding", 25,"justcoding@gmail.com"];
//字符串賦值 參數(shù)中只可以寫一個(gè)字符串 和第一種很像
NSString *str2 = [NSString stringWithString:@"我是字符串"];
//字符串轉(zhuǎn)換為utf-8格式 參數(shù)為char*類型
NSString *str3 = [NSString stringWithUTF8String:"字符串轉(zhuǎn)換utf-8格式"];
//字符串合并
int i = 100;
char*c = "xuanyusong";
NSString *temp = @"我是臨時(shí)字符串";
//在字符串temp的基礎(chǔ)繼續(xù)添加 int i 與 char* c 組成一個(gè)新的字符串
NSString *str4 = [temp stringByAppendingFormat:@"整型: %d 字符型 :%s",i,c];
//在字符串temp的基礎(chǔ)繼續(xù)添加temp 并組成一個(gè)新的字符串
NSString *str5 = [temp stringByAppendingString:temp];
遍歷
//經(jīng)典的字符串賦值
NSString *str = @"YUSONGMOMO";
//字符串的長度
int count = [str length];
NSLog(@"字符串的長度是%d",count);
//遍歷字符串中的每一個(gè)字符
for(int i =0; i < count; i++)
{
char c = [str characterAtIndex:i];
NSLog(@"字符串第 %d 位為 %c",i,c);
}
比較
NSString *str0 = @"justcoding";
NSString *str1 = @"justcoding";
//字符串完全相等比較
if([str0 isEqualToString:str1])
{
NSLog(@"字符串完全相等");
}
//字符串以開頭比較
if([str0 hasPrefix:@"just"])
{
NSLog(@"字符串str0以just開頭");
}
//字符串以結(jié)尾比較
if([str1 hasSuffix:@"coding"])
{
NSLog(@"str1字符串以coding結(jié)尾");
}
//考慮大小寫的比較
NSString *astring01 = @"This is a String!";
NSString *astring02 = @"this is a String!";
BOOL result = [astring01 compare:astring02] == NSOrderedSame/NSOrderedDescending(降)/NSOrderedAscending(升);
NSLog(@"result:%d",result);
//NSCaseInsensitiveSearch:不區(qū)分大小寫比較 NSLiteralSearch:進(jìn)行完全比較躲胳,區(qū)分大小寫 NSNumericSearch:比較字符串的字符個(gè)數(shù),而不是字符值纤勒。
NSString *string = @"0";
NSComparisonResult result = [string caseInsensitiveCompare:@"A"];
switch (result) {
case NSOrderedAscending:
NSLog(@"升冪");
break;
case NSOrderedSame:
NSLog(@"忽略大小寫相同的字串");
break;
case NSOrderedDescending:
NSLog(@"降冪");
break;
default:
NSLog(@"無法判定");
break;
}
理解objc_msgSend的作用
在OC中坯苹,如果向某對(duì)象傳遞信息,那就會(huì)使用動(dòng)態(tài)綁定機(jī)制來決定需要調(diào)用的方法摇天。在底層粹湃,所有方法都是普通的C語言函數(shù).
然而對(duì)象收到 消息后恐仑,究竟該調(diào)用哪個(gè)方法則完全于運(yùn)行期決定,甚至可以在程序運(yùn)行時(shí)改變为鳄,這些特性使得OC成為一門真正的動(dòng)態(tài)語言裳仆。
在OC中,給對(duì)象發(fā)送消息的語法是:
id returnValue = [someObject messageName:parameter];
這里孤钦,someObject叫做“接收者(receiver)”歧斟,messageName:叫做"選擇子(selector)",選擇子和參數(shù)合起來稱為“消息”。編譯器看到此消息后偏形,將其轉(zhuǎn)換為一條標(biāo)準(zhǔn)的C語言函數(shù)調(diào)用静袖,所調(diào)用的函數(shù)乃是消息傳遞機(jī)制中的核心函數(shù)叫做objc_msgSend,它的原型如下:
void objc_msgSend(id self, SEL cmd, ...)
第一個(gè)參數(shù)代表接收者俊扭,第二個(gè)參數(shù)代表選擇子队橙,后續(xù)參數(shù)就是消息中的那些參數(shù),數(shù)量是可變的萨惑,所以這個(gè)函數(shù)就是參數(shù)個(gè)數(shù)可變的函數(shù)捐康。
因此,上述以O(shè)C形式展現(xiàn)出來的函數(shù)就會(huì)轉(zhuǎn)化成如下函數(shù):
id returnValue = objc_msgSend(someObject,@selector(messageName:),parameter);
這個(gè)函數(shù)會(huì)在接收者所屬的類中搜尋其“方法列表”咒钟,如果能找到與選擇子名稱相符的方法吹由,就去實(shí)現(xiàn)代碼若未,如果找不到就沿著繼承體系繼續(xù)向上查找朱嘴。如果找到了就執(zhí)行,如果最終還是找不到粗合,就執(zhí)行消息轉(zhuǎn)發(fā)操作萍嬉。
注意:如果匹配成功的話,這種匹配的結(jié)果會(huì)緩存在“快速映射表”里面隙疚。每個(gè)類都有這樣一塊緩存壤追。所以如果將來再次向該類發(fā)送形同的消息,執(zhí)行速度就會(huì)更快了供屉。
==比較的是內(nèi)存地址(像strong)isEqual比較的是內(nèi)容(更像copy)
我們使用isMemberOfClass:能夠判斷出對(duì)象是否為某個(gè)特定類的實(shí)例行冰;
而isKindOfClass:方法能夠判斷出對(duì)象是否為某類或其派生類的實(shí)例。
這兩種方法都是利用了isa指針獲取對(duì)象所屬的類伶丐,然后通過super_class類在繼承體系中查詢悼做。在OC語言中,必須使用這種查詢類型信息的方法才能完全了解對(duì)象的真實(shí)類型哗魂。因?yàn)閷?duì)象類型無法在編譯期決定肛走。