點語法的死循環(huán)注意
在set方法和get方法別用點語法脓匿,否則會產生死循環(huá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)的一個類型轨奄。選擇器就是指向方法的一個指針汇跨。
可以簡單理解成:SEL其實是對方法的一種包裝呛占,將方法包裝成一個SEL類型的數(shù)據(jù)承粤。去找對應的方法地址。找到方法地址就可以調用方法闯团。
調用
//Person類中有 +test1方法和 -test2方法
Person *p = [Person new];
//調用對象方法 -test2 方法1
[p test2]
//方法2:利用sel間接調用
[p performSelector:@selector(test2)];
若調用的方法需要傳參數(shù)
[p test3:@"Wang"];
//或者用sel方法
[p performSelector:@selector(test3:)withObject:@"Wang"];
//注意:方法若有參數(shù)辛臊,則寫方法名不能漏了冒號:
創(chuàng)建SEL類型的數(shù)據(jù)
SEL s = @selector(test3);
copy,retain房交,assign的區(qū)別
retain :release舊值彻舰,retain新值(適用oc對象類型)。retain屬性表示兩個對象地址相同(建立一個指針候味,指針拷貝)刃唤,內容當然相同,這個對象的引用計數(shù)+1(引用計數(shù)變?yōu)?)白群。
assign :默認屬性 直接賦值尚胞,不改變引用計數(shù)(retainCount),適用于非oc對象類型帜慢,用于基礎數(shù)據(jù)類型 (NSInteger)和C數(shù)據(jù)類型(int,float, double, char,等)笼裳,其中int這樣的基本類型并不是對象,如果使用retain與copy會報錯粱玲。
copy :release舊值躬柬,copy新值。copy是創(chuàng)建一個新對象密幔,而retain是創(chuàng)建一個指針使對象引用計數(shù)加1楔脯。Copy屬性表示兩個對象內容相同,新的對象引用計數(shù)為1 胯甩,與舊有對象的引用計數(shù)無關昧廷,舊有對象沒有變化。copy減少對象對上下文的依賴偎箫。(如果牽扯到上面程序中兩個值互相影響的情況木柬,應該用copy)
總結一下,retain 是指針拷貝淹办,copy 是內容拷貝眉枕。
基本的數(shù)據(jù)類型
id類型:類似Java 的Object 類,可以轉換為任何數(shù)據(jù)類型怜森,id類型已經是指針了速挑,所以變量不需要加*
id foo=nil;
atomic,nonatomic readonly,readwrite
atomic是默認屬性副硅,保證setter/getter的原子性姥宝,即線程同步。nonatomic不保證原子性
readwrite為默認屬性恐疲,生成默認的setter/getter方法腊满。readonly只生成getter方法套么。
權限問題
private(自己):該類中的方法可以訪問這樣的變量,但不能被子類定義的方法直接訪問碳蛋。
protected(自己與子類):該類和任何的子類中的方法可以直接訪問這樣的變量胚泌,這是默認的。
public(自己肃弟,子類玷室,其他類):除了自己和子類中的方法外,也可以被其他類或者其他模塊中的方法所訪問愕乎。開放性最大阵苇,但最好避免使用這個作用域。其他類應該使用getter/setter方法來訪問或設置其他類上的實例變量感论,確保封裝性。
package:
注:默認的變量權限為protected紊册,方法只能為public
內存管理
概念
1.oc使用“引用計數(shù)(retainCount)”方式來管理內存比肄。當該對象創(chuàng)建時,該計數(shù)為1囊陡,說明有一個引用芳绩,如果不用時,就會減為0撞反,這就表示不再使用了妥色,那么就會銷毀該空間。
方法:
1.alloc, allocWithZone,new(帶初始化)
為對象分配內存遏片,retainCount為“1”嘹害,并返回此實例。
2.retain
retainCount 加“1”
3.copy,mutableCopy
復制一個實例吮便,retainCount數(shù)為“1”笔呀,返回此實例。所得到的對象是與其它上下文無關的髓需,獨立的對象(干凈對象)许师。
4.release
retainCount 減“1”,減到“0”時調用此對象的dealloc方法
5.autorelease
把當前對象放入了當前的Autoreleasepool中僚匆,當該pool被釋放時微渠,該pool中的所有Object會被調用Release
我們可以把上面的接口按對retainCount的操作性質歸為兩類,
A類是加一操作:1咧擂,2逞盆,3
B類是減一操作:4,5(延時釋放)
內存管理準則如下:
1屋确,A與B類的調用次數(shù)保持一制
2纳击,為了很好的保障準則一续扔,以實例對象為單位,誰A了就誰B焕数,沒有第二者參與
內存管理ARC
概念:
從XCode4.2開始就引入Automatic Reference Counting機制纱昧。我們創(chuàng)建的模板能看到@autoreleasepool{};
ARC使得你不需要再思考何時使用retain,release,autorelease這樣的函數(shù)來管理內存,它提供了自動評估內存生存期的功能堡赔,并且在編譯期間自動加入合適的管理內存的方法识脆。編譯器也會自動生成dealloc函數(shù)。
基本的ARC使用規(guī)則:
1.代碼中不能使用 release, retain, autorelease,dealloc, retainCount
2.不重載dealloc(如果是釋放對象內存以外的處理善已,是可以重載該函數(shù)的灼捂,但是不能調用[super dealloc])
3.不能使用NSAllocateObject, NSDeallocateObject
4.不能在C結構體中使用對象指針
5.id與void *間的如果cast時需要用特定的方法(__bridge關鍵字)
6.不能使用NSAutoReleasePool、而需要@autoreleasepool塊
7.不能使用“new”開始的屬性名稱
property 內存管理策略的選擇
1换团、非ARC下
①copy:只用于NSString悉稠、block
②retain:除NSString、block以外的OC對象
③assign:基本數(shù)據(jù)類型艘包、枚舉的猛、結構體(非OC對象)、當兩個對象相互引用時想虎,一端用retain卦尊,一端用assign
2、ARC下
①copy:只用于NSString舌厨、block
②strong:除NSString岂却、block以外的OC對象
③weak:當兩個對象相互引用,一端用strong裙椭,一端用weak
④assign:基本數(shù)據(jù)類型躏哩、枚舉、結構體(非OC對象)
字典類型 NSDictionary 和 NSMutableDictionary
概念
1.字典類型 NSDictionary 和 數(shù)組NSArray? 類型相似骇陈,但存在數(shù)組里要取值每次都要遍歷震庭,這樣就浪費了很長的時間,字典的便利就在于他在存取對象的時候你雌,在后面會追加一個 鍵值器联,可以理解成一個標志,我們可以根據(jù)這個標志很快的找到這個對象婿崭,這樣就相對于數(shù)組的全部遍歷就要方便多拨拓。
2.字典類型與數(shù)組類型相似,都是存取的對象氓栈,不能存取基本的數(shù)據(jù)類型渣磷,如 int , double, char等,類比數(shù)組授瘦,字典自然也會有兩種類型醋界,不可變字典: NSDictionary 和 可變字典 NSMutableDictionary
3.字典中的數(shù)據(jù)是以 鍵值對 的形式出現(xiàn)竟宋,并且順序不能亂,前邊是對象形纺,后面是鍵名
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 這個結果的順序不是固定的丘侠,因為查找的方法為哈希查找,所以數(shù)組的順序有可能不是你所定義的順序
NSArray *keysAll = [dic1 allKeys];
//全部的value 這個結果的順序也不是固定的
NSArray *valuesAll = [dic1 allValues];
//取出值為Yue的所有key值
NSArray *key = [dic1 allKeysForObject:arrayA];
//取出key值為name的對象(萬物皆對象)
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ù)組中總共有多少個對象蜗字。
NSLog(@"個數(shù):%lu",(unsigned long)arrayA.count);
NSLog(@"個數(shù):%lu",(unsigned long)[arrayB count]);
//2、獲取數(shù)組中下標對應的元素對象.(下標是從0開始)
NSLog(@"獲取下標為1的元素:%@" ,[arrayA objectAtIndex:1]);
//3脂新、在當前數(shù)據(jù)中追加一個新的對象挪捕,并且返回一個新的數(shù)據(jù)對象(新的數(shù)組對象和被追加的對象,是兩個不同的數(shù)組對象)争便。
NSLog(@"重組數(shù)組 組成新數(shù)組:%@" ,[arrayA arrayByAddingObject:@"F"]);
//4纽什、在當前的數(shù)組中追加一個新的數(shù)據(jù)扔涧,并且返回一個新的數(shù)組對象置尔。
NSLog(@"2個數(shù)組重組組成新數(shù)組:%@",[arrayA arrayByAddingObjectsFromArray:arrayB]);
//5趋惨、使用當前的數(shù)組生成一個字符串,新生成的字符串使用提供的separator字符進行分割酷宵。
NSLog(@"分割成字符串%@",[arrayA componentsJoinedByString:@","]);
//6、檢測數(shù)據(jù)中是否包含指定的對象元素
NSLog(@"arrayA是否有1:%i躬窜,arrayA是否有A:%i",[arrayA containsObject:@"1"],[arrayA containsObject:@"A"]);
//7浇垦、使用當前的數(shù)組生成字符串。允許一個對象返回一個字符串來描述它的內容荣挨;這個常用于調試debugging
NSLog(@"重寫改變生成字符串:%@",[arrayA description]);
//? ? 8男韧、根據(jù)設置的locale 進行連接數(shù)組
//? ? NSLog(@"連接數(shù)組1:%@",[arrayA descriptionWithLocale:@"4"]);
//? ? NSLog(@"連接數(shù)組2:%@",[arrayA descriptionWithLocale:arrayB indent:1]);
//9、兩個數(shù)組的第一個元素是否相同默垄,如果相同此虑,則返回 數(shù)組中,第一個元素的字符串口锭,反之朦前,返回null 對象
NSLog(@"兩個數(shù)組的第一個元素是否相同:%@",[arrayA firstObjectCommonWithArray:arrayB]);
//10、 從數(shù)組中獲取NSRange對象的數(shù)據(jù)存放到objects 中鹃操,NSRange的數(shù)據(jù)標示從location,開始后面length 個數(shù)據(jù)
//-(void)getObjects:(id__unsafe_unretained [])objects range:(NSRange)range;
//11韭寸、 判斷制定的anObject 對象是否存在數(shù)組中如果存在返回,對象所在的下標
NSUInteger index= [arrayA indexOfObject:@"C"];
if (index == NSNotFound) {
NSLog(@"不在");
}else{
NSLog(@"對象所在的下標:%lu",index);
}
//11-1荆隘、 判斷制定的元素恩伺,是否在數(shù)組中,數(shù)組查詢的位置椰拒,是從range.location 的位置開始晶渠,到range.length 的長度結束
NSUInteger index1= [arrayA indexOfObject:@"C" inRange:NSMakeRange(0, 2)];
if (index1 == NSNotFound) {
NSLog(@"不在");
}else{
NSLog(@"對象所在的下標1:%lu",index1);
}
//12凰荚、比較兩個數(shù)組是否相同 ,數(shù)組長度相同褒脯,并且相同位置上的元素也相同便瑟。
NSLog(@"兩個數(shù)組是否相同:%i",[arrayA isEqualToArray:arrayB]);
//13、返回最有一個元素憨颠,如果一個數(shù)組的長度為0 返回的對象為nil
NSLog(@"arrayA最后一個:%@,arrayA第一個:%@",[arrayA lastObject],[arrayA firstObject]);
//? ? 15胳徽、使用數(shù)組返回一個 NSEnumerator 對象,這個對象類似與一個指針爽彤,可以用來遍歷 整個數(shù)組 指針從前向后遍歷
//? ? NSEnumerator *enu = [arrayA objectEnumerator];
//? ? NSLog(@"enu:%@",enu);
//這是用來排序的函數(shù)养盗,comparator 這個參數(shù),需要傳入一個返回結果是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ù)嚷节,并放置到一個新的數(shù)組中
NSLog(@"arrayA第1個起后2個數(shù)%@",[arrayA subarrayWithRange:NSMakeRange(1, 2)]);
//22聂儒、寫入數(shù)組中的數(shù)據(jù),到指定path 的目錄中:
BOOL q = [arrayA writeToFile:@"path" atomically:YES];
NSLog(@"%i",q);
//23硫痰、如同上面的方法一樣衩婚,所不同的是寫入數(shù)組中的內容到 網上指定的路徑。
BOOL q1 = [arrayA writeToURL:[NSURL URLWithString:@"網上的路徑"] atomically:YES];
NSLog(@"%i",q1);
//26效斑、 用來根據(jù)indexes 獲取一個數(shù)組非春, NSIndexSet 是一個用來管理 index 的對象。
NSLog(@"arrayA第一個:%@",[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缓屠、返回指定下標的一個對象奇昙。這個方法類似 objectAtIndex:
NSLog(@"arrayA第4個:%@",[arrayA objectAtIndexedSubscript:4]);
//28、使用block 塊遍歷整個數(shù)組敌完。這個block 需要三個參數(shù)储耐,id obj 表示數(shù)組中的元素。
//NSUInteger idx 標示元素的下標滨溉,
//bool *stop 是一個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什湘、 同上面的方法一項,不過NSIndexSet 參數(shù)標示业踏,根據(jù)下標取出的數(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ù)條件用來獲取一個NSUIndex 對象腹尖,主要是根據(jù)條件進行數(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 、 這個方法添加了參數(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、對數(shù)組進行排序操作 參數(shù)cmptr 是一個block 函數(shù)塊绎巨,返回的數(shù)據(jù)類型是一個NSComparisonResult 對象
NSArray *comparator = [arrayA sortedArrayUsingComparator:^NSComparisonResult(NSString *s1, NSString *s2) {
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近尚、進行排序操作,NSSortOptions 排序的參數(shù) 用來表示是同時排序场勤,還是穩(wěn)定執(zhí)行戈锻。
NSArray *test111 = [arrayA sortedArrayWithOptions:NSSortStable usingComparator:^ NSComparisonResult (NSString *s,NSString *s2){
if(s.length < s2.length){
return NSOrderedAscending;
}
if(s.length > s2.length){
return NSOrderedDescending;
}
return NSOrderedSame;
}];
NSLog(@"test111:%@",test111);
基礎框架類
NSData:序列字節(jié),不可修改和媳。要修改的話需要用到NSData子類NSMutableData格遭。NSData主要用于從網上下載數(shù)據(jù)(以NSData對象返回數(shù)據(jù));把對象存儲在文件中留瞳;讀取文件數(shù)據(jù)(將NSData對象當做緩存區(qū))拒迅。
NSSet:無序的不同對象的集合,不可變她倘,可通過調用方法增加或刪除一個集合來獲得新的NSSet對象璧微。它的子類是NSMutableSet。
NSDictionary:其鍵值對的無序集合硬梁,鍵通常是NSString前硫,值可以是任何一個對象,NSDictionary是定長的荧止,它的變長子類是NSMutableDictionary开瞭。
屬性列表
NSObject:每個類都是從NSObject繼承來的,它采用 NSObject協(xié)議,它實現(xiàn)了與 NSCopying罩息、 NSMutableCopying和 NSCoding 協(xié)議相關的方法,
繼承个扰,重寫覆蓋瓷炮,重載
方法重寫:若子類中的方法與父類的某一方法具有相同的方法名、返回類型和參數(shù)表递宅,則新方法覆蓋原有方法娘香。
方法重載:類中可以創(chuàng)建多個方法,他們具有相同的方法名办龄,但具有不同的參數(shù)和不同的定義烘绽,調用方法時通過傳遞給他們不同個數(shù)和類型的參數(shù)來決定使用哪個方法。 方法名一定相同俐填;方法的參數(shù)表必須不同安接,包括參數(shù)的個數(shù)和類型,以此區(qū)分不同的方法體英融; 方法的返回類型和修飾符可以相同也可以不同盏檐。
self:一個類中的方法調用同一個類的另一個方法是使用self歇式,代表本身,相當于this胡野。
super:表示父類材失,可以使用super訪問父類中被子類隱藏或重寫的方法。
1.oc中只能單繼承硫豆,即一個類只有一個父類
2.子類可以重寫父類的方法龙巨,對其進行覆蓋。
子類內部還能調用父類的該方法熊响,使用super
[super? method];
3.oc不支持重載旨别,即使參數(shù)不一樣也不能使用同名方法