OCfoudation框架(下)
前面學習了有關OCfoudation框架的部分內容,我們現在對于后面的內容繼續學習。
文章目錄
- OCfoudation框架(下)
- 數組(NSArray和NSMutableArray)
- 對集合元素整體調用方法
- 排序
- 使用枚舉器遍歷元素
- 快速枚舉(for in)
- 可變數組
- 集合(NSSet 與 NSMutableSet)
- 功能與用法
- 判斷元素重復的標準
- NSMutableSet的功能和用法
- NSCountedSet的用法
- 有序集合
- 字典
- 功能和用法
- 對key排序
- 對key進行過濾
- 用自定義類作為key
- NSmutableDictionary
數組(NSArray和NSMutableArray)
創建數組的常見方法介紹:
- arrary:創建一個不包含任何元素的空NSArray
- arrayWithContentsOfFile:/initWithContentsOfFile:讀取文件內容來創建
- arrayWithObject:創建僅包含指定元素的NSArray
- arrayWithObjects:創建包含指定的N個元素的NSArray;
下面我們通過一段代碼來運用這個數組的一些方法。
int main(int argc, const char * argv[]) {@autoreleasepool {NSArray* array = [NSArray arrayWithObjects:@"iOS", @"Android", @"Java講義", @"Html", @"structs", @"nanxun", nil];NSLog(@"first: %@",[array objectAtIndex:0]);NSLog(@"last:%@", [array lastObject]);NSArray* arr1 = [array objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(2, 3)]];NSLog(@"%@",arr1);NSLog(@"Android:%ld", [array indexOfObject:@"Android"]);NSLog(@"Android in (2,5): %ld", [array indexOfObject:@"Android" inRange:NSMakeRange(2, 3)]);array = [array arrayByAddingObject:@"nannan"];array = [array arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:@"krystal", @"zitai", nil]];for (int i = 0; i < array.count; i++) {NSLog(@"%@", [array objectAtIndex:i]);}NSArray* arr2 = [array subarrayWithRange:NSMakeRange(5, 3)];[arr2 writeToFile:@"/Users/nanxun/Documents/testoc/foudation study/foudation study/myFile.txt" atomically:YES];}return 0;
}
打印結果如下:
接下來分析一下相關內容,先看我們在(2, 5)位置尋找Android的結果,發現他是一個數字9223372036854775807,這個數值實際上是NSNotFound這個常量的值,就下來我們通過兩種方式在后面添加元素,arrayByAddingObject添加單個元素,arrayWithObjects方法是將一個數組中的元素全部追加到原數組后面。
同時可以看到,我門用程序直接輸出數組的話,可知道中文無法正常輸出,這個會轉化成/U75af格式輸出。
我們下面分析在NSArray中能否判斷指定元素位于NSArray集合中的索引,我們的標準是什么?這個標準就是我們的isEqual: 方法,比較是否相同,為了理解這個部分的內容,我們建立一個FKUser來幫助自己理解相關內容。
接口部分
@interface FKUser : NSObject
@property (nonatomic, copy) NSString* name;
@property (nonatomic, copy) NSString* pass;
- (id) initWithName:(NSString*) aName pass:(NSString*) aPass;
- (void) say:(NSString*) content;
@end
實現部分
@implementation FKUser
- (id) initWithName:(NSString *)aName pass:(NSString *)aPass {if (self = [super init]) {self.name = aName;self.pass = aPass;}return self;
}
- (void) say:(NSString *)content {NSLog(@"%@說:%@", self.name, content);
}
- (BOOL) isEqual:(id)object {if (self == object) {return YES;}if ([object class] == [FKUser class]) {FKUser* target = (FKUser*) object;return [self.name isEqualToString:target.name] && [self.pass isEqualToString: target.pass];}return NO;
}
- (NSString*) description {return [NSString stringWithFormat:@"FKUser[_name = %@, _pass = %@]", self.name, self.pass];
}
@end
主函數部分
int main(int argc, const char * argv[]) {@autoreleasepool {NSArray* array = [NSArray arrayWithObjects:[[FKUser alloc] initWithName:@"sun" pass:@"123"],[[FKUser alloc] initWithName:@"bai" pass:@"345"],[[FKUser alloc] initWithName:@"zhu" pass:@"654"],[[FKUser alloc] initWithName:@"tang" pass:@"178"],[[FKUser alloc] initWithName:@"niu" pass:@"155"], nil];FKUser* newUser = [[FKUser alloc] initWithName:@"zhu" pass:@"654"];NSUInteger pos = [array indexOfObject:newUser];NSLog(@"newUser的位置為%ld", pos);}return 0;
}
輸出結果為下:
這里我們發現了一個事情就是我們重新創建了一個對象,雖然該對象與集合中的任何對象都不相同,但是我們的程序還是可以返回該FKUser對象在該集合中的索引,這是因為他調用的是我們的isEqual方法
對集合元素整體調用方法
如果只是簡單的調用集合元素的方法,主要有兩種方法:
- makeObjectPerformSelector:依次調用NSArray集合中每個元素的指定方法需要傳入一個SEL參數
- makeObjectsPerformSelcetor:withObject:一次調用集合中每個元素的指定方法,該方法第一個參數SEL用于指定調用那個方法,第二個參數用于調用集合元素方法時候傳入參數;第三參數用來控制是否終止迭代,如果在處理某個元素后,將第三個元素復制為YES,該方法就終止迭代調用。
如果希望對集合中所有元素進行隱式遍歷,并使用集合元素來執行某一段代碼,可以使用以下三種方式
- enumerateObjectUsingBlock: 遍歷集合中的所有元素,并依次使用元素來執行指定的代碼塊
- enumerateObjectsWithOptions:usingBolck: 和上面的差別就是可以傳入一個號控制遍歷的選項。
- enumerateObjectAtIndexes:options:usingBlock: 這個它增加了一個遍歷指定范圍內的元素,并一次使用元素來執行指定的代碼塊。
int main(int argc, const char * argv[]) {@autoreleasepool {NSArray* array = [NSArray arrayWithObjects:[[FKUser alloc] initWithName:@"sun" pass:@"123"],[[FKUser alloc] initWithName:@"bai" pass:@"345"],[[FKUser alloc] initWithName:@"zhu" pass:@"654"],[[FKUser alloc] initWithName:@"tang" pass:@"178"],[[FKUser alloc] initWithName:@"niu" pass:@"155"], nil];[array makeObjectsPerformSelector:@selector(say:) withObject:@"下午好,NSArray真強大"];NSString* content = @"瘋狂iOS講義";[array enumerateObjectsAtIndexes: [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(2, 2)]options:NSEnumerationReverse usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {NSLog(@"正在處理第%ld個元素,%@",idx, obj);[obj say:content];}];}return 0;
}
打印結果如下:
這兩段代碼,主要調用了兩個函數,一個是調用了**makeObjectsPerformSelector:**方法通過withObjects為say方法傳入參數.
第二個則是應用了enumerateObjectsAtIndexes:options:usingBlock:方法并用這些元素來這些指定的代碼塊,傳入的代碼塊參數就代表程序對每個集合元素迭代執行的代碼體。(筆者這里對與Block不了解,還需要后續學習進行補充)。
排序
對數組的排序函數主要有三種:
- sortedArrayUsingFunction:contes:該方法使用排序函數對集合元素進行一個排序,該排序函數必須返回NSOrderedDesceding,NSOrderedAscending,NSOrderedSame三個枚舉常量。
- sortedArrayUsingSelector:該方法使用集合元素自身的方法對集合元素進行排序,它的排序函數同樣會返回上面給出的三個枚舉值。
- sortedArrayUsingComparator:該方法使用代碼塊對與集合元素進行排序
三種方法的返回值都是一個排好序的NSArray對象。
下面演示一下我們對于NSArray集合元素進行一個排序。
NSInteger inSort (id num1, id num2, void* context) {int v1 = [num1 intValue];int v2 = [num2 intValue];if (v1 < v2) {return NSOrderedAscending;} else if (v1 == v2) {return NSOrderedSame;} else {return NSOrderedDescending;}
}
int main(int argc, const char * argv[]) {@autoreleasepool {NSArray* array1 = [NSArray arrayWithObjects:@"C++",@"Python",@"Perl",@"C",@"Objective-C",@"Ruby", nil];array1 = [array1 sortedArrayUsingSelector:@selector(compare:)];NSLog(@"%@", array1);NSArray* array2 = [NSArray arrayWithObjects:[NSNumber numberWithInt:20], [NSNumber numberWithInt:12], [NSNumber numberWithInt:-8],[NSNumber numberWithInt:50], [NSNumber numberWithInt:19],nil];array2 = [array2 sortedArrayUsingFunction:inSort context:nil];NSLog(@"%@", array2);NSArray* array3 = [array2 sortedArrayUsingComparator:^(id obj1, id obj2) {if ([obj1 intValue] > [obj2 intValue]) {return NSOrderedDescending;} else if ([obj1 intValue] < [obj2 intValue]) {return NSOrderedAscending;} else {return NSOrderedSame;}}];NSLog(@"%@", array3);}return 0;
}
打印結果如下:
在上述代碼中間我們示范了三種對于NSArrary進行排序的三種方法,第一種是調用NSString自身的compaer:方法進行排序(compare的比較和成語言中的strcmp()函數相似)。
后面是兩種不同的方法,一個是調用代碼塊,一個是調用函數的方法。
使用枚舉器遍歷元素
我們有兩個方法獲得枚舉器
- objectEnumerator:正序遍歷
- reverseObjectEnumerator:逆序遍歷
枚舉器的方法有以下兩個
- allObjects:獲取枚舉集合中所有的元素
- reverseObjectEnumerator:獲取被枚舉集合中的下一個元素。
int main(int argc, const char * argv[]) {@autoreleasepool {NSArray* array1 = [NSArray arrayWithObjects:@"C++",@"Python",@"Perl",@"C",@"Objective-C",@"Ruby", nil];NSEnumerator* en = [array1 objectEnumerator];id object;while (object = [en nextObject]) {NSLog(@"%@", object);}NSLog(@"");NSEnumerator* an = [array1 reverseObjectEnumerator];while (object = [an nextObject]) {NSLog(@"%@", object);}}return 0;
}
打印結果為:
一種是升序,另一種是降序。
快速枚舉(for in)
快速枚舉的語法格式如下:
for(type variableName in collection) {//variableName自動迭代訪問每一個元素
}
tips:這里面如果用快速枚舉來遍歷NSDictionary對象的時候,它代表的是key值
下面給出一個示范
int main(int argc, const char * argv[]) {@autoreleasepool {NSArray* array1 = [NSArray arrayWithObjects:@"C++",@"Python",@"Perl",@"C",@"Objective-C",@"Ruby", nil];for (id object in array1) {NSLog(@"%@", object);}}return 0;
}
打印結果如下
可變數組
NSArray代表元素不可變的集合,一旦創建成功,程序不能向集合調價新的元素,這時候我們就要運用到我們的NSMutableArray.
它給出了增加(add),刪除(remove),替換(replace)元素的方法。
NSMutableArray還提供了sortUsingSelector:、sortUsingComparator:、sortUsingFunction: context:方法,它們與前面介紹的NSArray的排序的方法類似,區別是NSArray的排序的方法返回的是一個新的NSArray對象,而NSMutableArray返回的是排序后的原來的對象。
下面給出代碼示范
NSString *NSCollectionToString(NSArray *array) { // 將集合中的所有元素合成一個字符串便于我們打印NSMutableString *result = [NSMutableString stringWithString:@"["];for (id obj in array) {[result appendString: [obj description]];[result appendString:@","];}NSUInteger len = [result length];[result deleteCharactersInRange:NSMakeRange(len - 1, 1)];//去掉最后一個字符[result appendString:@"]"];return result;
}
int main(int argc, const char * argv[]) {@autoreleasepool {NSMutableArray* array1 = [NSMutableArray arrayWithObjects:@"C++",@"Python",@"Perl",@"C",@"Objective-C",@"Ruby", nil];[array1 addObject:@"Java"];NSLog(@"%@", NSCollectionToString(array1));[array1 addObjectsFromArray:[NSArray arrayWithObjects:@"Js", @"Ts", nil]];NSLog(@"%@", NSCollectionToString(array1));[array1 insertObject:@"Android" atIndex:2];NSLog(@"%@", NSCollectionToString(array1));[array1 insertObjects:[NSArray arrayWithObjects:@"web",@"server", nil] atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(3, 2)]];NSLog(@"%@", NSCollectionToString(array1));[array1 removeLastObject];NSLog(@"%@", NSCollectionToString(array1));[array1 removeObjectAtIndex:5];NSLog(@"%@", NSCollectionToString(array1));[array1 replaceObjectAtIndex:2 withObject:@"瘋狂iOS"];NSLog(@"%@", NSCollectionToString(array1));}return 0;
}
打印結果如下:
集合(NSSet 與 NSMutableSet)
NSSet集合不允許包含相同的元素(它沒有明顯的順序),如果試圖將兩個相同的元素放在同一個NSSet集合中,則只會保留一個元素
功能與用法
實際上,NSArray與NSSet依然有大量的相似之處。
- 都可以通過count方法獲取集合元素數量
- 可以用快速枚舉遍歷集合元素
- 可以通過objectEnumerator方法獲取NSEnumerator枚舉器對集合元素遍歷。
- 提供了makeObjectsPerformSelector:方法對集合元素真題調用某個方法
接下來我們介紹一下NSSet的常用方法
- setByAddingObject:向集合中添加一個新元素,返回添加元素后的新集合
- setByAddingObjectsFromSet:使用NSSet集合向集合中添加多個新元素,返回新集合
- setByAddingObjectsFromArray:使用NSArray集合向集合中添加多個新元素,返回新集合
- allObjects:返回集合中所有元素組成的NSArray
- anyObject:返回集合中的某個元素。(但是并不保證隨機返回集合元素)。
- containsObject:判斷集合是否包含指定元素
- Member:判斷該集合是否包括與該參數相等的元素,如果包含就返回相等的元素,反之則返回nil。
- objectsPassingTest:需要傳入一個代碼塊對集合元素進行一個過濾,滿足該代碼塊的集合元素會被保留下來并組成一個新的NSSet集合作為返回值
- objectsWithOptions:passingTest:和前一個方法的功能基本相似,只是可以額外地傳入一個NSEnumerationOptions作為迭代參數
- isSubsetOfSet:判斷是否為一個子集
- intersectsSet:判斷是否有交集
- isEqualToset:判斷集合是否相同
下面給出一段代碼來理解相關內容
NSString *NSCollectionToString(id array) {NSMutableString *result = [NSMutableString stringWithString:@"["];for (id obj in array) {[result appendString: [obj description]];[result appendString:@","];}NSUInteger len = [result length];[result deleteCharactersInRange:NSMakeRange(len - 1, 1)];//去掉最后一個字符[result appendString:@"]"];return result;
}
int main(int argc, const char * argv[]) {@autoreleasepool {NSSet* set1 = [NSSet setWithObjects:@"iOS", @"Andirod",@"web",@"server", nil];NSLog(@"set個數為%ld", [set1 count]);NSLog(@"%@", NSCollectionToString(set1));NSSet* set2 = [NSSet setWithObjects:@"krystal",@"xiyang",@"fenfneko",@"web", nil];NSLog(@"%@", NSCollectionToString(set2));set1 = [set1 setByAddingObject:@"shenyi"];NSSet* s1 = [set1 setByAddingObjectsFromSet:set2];NSLog(@"并集合%@", NSCollectionToString(s1));BOOL bo = [set2 isSubsetOfSet: set1];NSLog(@"set2是否是set1子集集%ld",bo);BOOL bb = [set1 containsObject:@"Andirod"];NSLog(@"是否包含Andirod:%ld", bb);NSLog(@"從set1中取出一個%@",[set1 anyObject]);NSSet* fileteredSet = [set1 objectsPassingTest:^(id obj, BOOL *stop) {return (BOOL)([obj length] > 3);}];NSLog(@"set1中元素長度大于8的集合元素有%@",NSCollectionToString(fileteredSet));}return 0;
}
下面是代碼的結果:
這部分內容主要是一個演示相關代碼的一個作用。
判斷元素重復的標準
這里涉及到了一個Hash表的內容,我們每存入一個元素那么我們的NSSet會帶調用該對象的一個Hash方法來計算一個Hash值,然后根據HashCode計算出元素在底層Hash表中的存儲位置。如果出現了兩個元素通過了isEqual方法但是它倆的值相同,那么我們這里的方式是通過鏈表將這兩個元素連接起來。
這里我們就可以知道NSSet中判斷兩個元素是否相等的標準如下:
- 兩個對象通過isEqual的方法返回YES
- 兩個對象的hash方法的返回值也相等
int main(int argc, const char * argv[]) {@autoreleasepool {NSSet* array = [NSSet setWithObjects:[[FKUser alloc] initWithName:@"sun" pass:@"123"],[[FKUser alloc] initWithName:@"bai" pass:@"345"],[[FKUser alloc] initWithName:@"zhu" pass:@"123"],[[FKUser alloc] initWithName:@"tang" pass:@"178"],[[FKUser alloc] initWithName:@"niu" pass:@"155"], nil];NSLog(@"元素個數為%ld", [array count]);NSLog(@"%@", NSCollectionToString(array));}return 0;
}
這是我們之前用過的FKUser類別,我們在這個類別中間定義了我們的isEqual:方法它只要name和oass相同就說明了我們的兩個對象是相同的。但是打印結果卻不符合我們的一個預期
發現出現了兩個相同的元素,因此我們要重寫一下Hash方法。
- (NSUInteger) hash {NSLog(@"===hash===");NSUInteger nameHash = _name == nil ? 0 : [_name hash];NSUInteger passHash = _pass == nil ? 0 : [_pass hash];return nameHash * 31 + passHash;
}
修改之后發現結果就恢復正常了。
這里我們發現了我們執行了5次Hash方法,這一步說明我們每次添加一個集合與安素,總是會先調用該元素的Hash方法,在重寫這兩種方法的時候,我們的目的主要是為了滿足NSSet的性質,為了保證哦我們的NSSet保持一個較高的性能。
tips:Hash方法對于NSSet是非常重要的,下面給出重寫Hash方法的基本原則。
- 同一對象返回的Hash值應該是相同的
- isEqual:方法比較返回YES的時候,這兩個對象的Hash應返回相等的值·
- 對象中所有被isEqual比較標準的實例變量都應該用來就算hashCode值。
一般情況我們的返回值都寫成[f1 hash] * (質數) + [f2 hash]
。
NSMutableSet的功能和用法
和array相似,add(增加),remove(刪除)。
主要要記住交,并,交,差集的函數
- unionSet:計算并集
- minusSet:計算差集
- intersectSet:計算交集
- setSet:用后一個元素替換已有集合中的所有元素
int main(int argc, const char * argv[]) {@autoreleasepool {NSMutableSet* set1 = [NSMutableSet setWithCapacity:10];[set1 addObject:@"Java"];NSLog(@"add a one %@",NSCollectionToString(set1));[set1 addObjectsFromArray:[NSArray arrayWithObjects:@"krystal",@"xiyang",@"zzr", nil]];NSLog(@"add many %@", NSCollectionToString(set1));[set1 removeObject:@"xiyang"];NSLog(@"remove one %@",NSCollectionToString(set1));NSMutableSet* set2 = [NSSet setWithObjects:@"fenfenko",@"shenyi", nil];//[set1 unionSet: set2];//[set1 minusSet: set2];//[set1 intersectSet:set2];[set1 setSet:set2];NSLog(@"%@", NSCollectionToString(set1));}return 0;
}
打印結果如下:
NSCountedSet的用法
NSCountedSet主要是有一個特色就是它會為每一個元素增加一個該元素出現的個數,我們可以不可以添加元素,但是如果我們添加的元素重復了,但是會將該元素的添加次數加1.刪除元素的時候也是將這個元素添加次數減1,知道它為0的時候,這個元素才會真正的從NSCountedSet中刪除。
int main(int argc, const char * argv[]) {@autoreleasepool {NSCountedSet* set1 = [NSCountedSet setWithObjects:@"iOS講義",@"Android",@"Java", nil];[set1 addObject:@"Java"];[set1 addObject:@"Java"];NSLog(@"%@", NSCollectionToString(set1));NSLog(@"Java的添加次數為%ld", [set1 countForObject:@"Java"]);[set1 removeObject:@"Java"];NSLog(@"%@", NSCollectionToString(set1));NSLog(@"Java的添加次數為%ld", [set1 countForObject:@"Java"]);[set1 removeObject:@"Java"];[set1 removeObject:@"Java"];NSLog(@"%@", NSCollectionToString(set1));NSLog(@"Java的添加次數為%ld", [set1 countForObject:@"Java"]);}return 0;
}
打印結果為:
這里就很好的體現了我們的NSCountedSet的特色。
有序集合
NSOrderedSet最主要的點在于可以保持與安素的添加順序,而且每一個元素都有縮影,可以根據縮影來操作元素。
int main(int argc, const char * argv[]) {@autoreleasepool {NSOrderedSet* set = [NSOrderedSet orderedSetWithObjects:[NSNumber numberWithInt:40],[NSNumber numberWithInt:12],[NSNumber numberWithInt:-9],[NSNumber numberWithInt:20], nil];NSLog(@"first :%@", [set firstObject]);NSLog(@"last:%@", [set lastObject]);NSLog(@"索引為2的元素:%@", [set objectAtIndex:2]);NSIndexSet* indexSet = [set indexesOfObjectsPassingTest:^(id obj, NSUInteger idx, BOOL* stop) {return (BOOL)([obj intValue] > 10); // 返回大于10的值}];NSLog(@"%@", indexSet);}return 0;
}
字典
這里的字典和C++中的map大致相同,它擁有一個鍵值對,所有key放在一個Set集合中,但是如果我們采用一個allKeys方法來返回卻是一個NSArray。
功能和用法
初始化方法:一般以dictionary開頭
訪問方式:
@implementation NSDictionary (print)
- (void)print {NSMutableString* result = [NSMutableString stringWithString:@"["];for (id key in self) {[result appendString:[key description]];[result appendString:@"="];[result appendString:[self[key] description]];[result appendString:@", "];}NSUInteger len = [result length];[result deleteCharactersInRange:NSMakeRange(len - 1, 1)];[result appendString:@"]"];NSLog(@"%@", result);
}
這段代碼演示了兩種經典的語法,通過key獲取value值 self[key]
下面給出一段代碼來演示相關內容。
int main(int argc, const char * argv[]) {@autoreleasepool {NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:[[FKUser alloc] initWithName:@"krystal" pass:@"24"], @"one", [[FKUser alloc] initWithName:@"xiyang" pass:@"33"], @"two",[[FKUser alloc] initWithName:@"flandre" pass:@"111"], @"three", [[FKUser alloc] initWithName:@"fenfenko" pass:@"2222"], @"four",[[FKUser alloc] initWithName:@"krystal" pass:@"24"], @"five", nil];[dict print];NSLog(@"有多少個key-value對:%ld", [dict count]);NSLog(@"dict的所有key為%@", [dict allKeys]);NSLog(@"krystal對應的所有key為%@", [dict allKeysForObject:[[FKUser alloc] initWithName:@"krystal" pass:@"24"]]);NSEnumerator* en = [dict objectEnumerator];NSObject* value;while (value = [en nextObject]) {NSLog(@"%@", value);}[dict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL* stop) {NSLog(@"key的值為:%@",key);[value say:@"101牛逼"];}];}return 0;
}
這里就演示了我們的dictionary的相關的代碼演示。
對key排序
他和對于數組的排序一樣,都是類似的,它的返回值同樣是那三個關鍵字:NSOrderedAscending,NSOrderedDescending,NSOrderedSame。
接下來示范一下排序。
NSString *NSCollectionToString(id array) {NSMutableString *result = [NSMutableString stringWithString:@"["];for (id obj in array) {[result appendString: [obj description]];[result appendString:@","];}NSUInteger len = [result length];[result deleteCharactersInRange:NSMakeRange(len - 1, 1)];//去掉最后一個字符[result appendString:@"]"];return result;
}
int main(int argc, const char * argv[]) {@autoreleasepool {NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:@"iOS",@"one",@"Android",@"two",@"Java",@"three",@"Objective-c",@"four", nil];[dict print];NSArray* keyArr1 = [dict keysSortedByValueUsingSelector:@selector(compare:)];NSLog(@"%@", keyArr1);NSArray* keyArr2 = [dict keysSortedByValueUsingComparator:^(id value1, id value2) {if ([value1 length] > [value2 length]) {return NSOrderedDescending;} else if ([value1 length] == [value2 length]) {return NSOrderedSame;} else {return NSOrderedAscending;}}];NSLog(@"%@", keyArr2);}return 0;
}
打印結果如下
對key進行過濾
- keysOfEntriesPassingTest:使用代碼塊迭代處理key-value對,只有符合代碼塊條件的會留下來。一共接收三個參數,第一個是正在迭代處理的key,第二個參數代表正在迭代處理的value,第三個參數代表是是否需要繼續迭代,如果第三個參數設置成NO,這個方法就會立即停止迭代。
- keysOfEntriesWithOptions:passingTest:該方法的功能和前一個方法的功能基本相同,可以額外傳入一個附加的NSEnumerationOptions的選項參數。
int main(int argc, const char * argv[]) {@autoreleasepool {NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:89], @"Objective-C",[NSNumber numberWithInt:69], @"Ruby",[NSNumber numberWithInt:75], @"Python",[NSNumber numberWithInt:109], @"Prel", nil];[dict print];NSSet* keySet = [dict keysOfEntriesPassingTest:^(id key, id value, BOOL* stop) {return (BOOL)([value intValue] > 80);}];NSLog(@"%@", keySet);}return 0;
}
打印結果如下:
用自定義類作為key
我們可以用自己定義的類來作為key,但是要滿足兩個要求:
- 正確重寫isEqual:方法和hash方法
- 自定義類實現了copyWithZone:方法,最好可以返回對象的不可變副
int main(int argc, const char * argv[]) {@autoreleasepool {FKUser* u1 = [[FKUser alloc] initWithName:@"krystal" pass:@"24"];NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:@"one", [[FKUser alloc] initWithName:@"xiyang" pass:@"23"],@"two", [[FKUser alloc] initWithName:@"flandre" pass:@"22"],@"three", [[FKUser alloc] initWithName:@"xiyang" pass:@"23"],@"four", [[FKUser alloc] initWithName:@"fenfenko" pass:@"19"],@"five", [[FKUser alloc] initWithName:@"niu" pass:@"155"],@"six", u1, nil];u1.pass = nil;[dict print];}return 0;
}
打印結果如下:
這里我們可以看到它會讓重復的key出現一次。
NSmutableDictionary
它其實也主要是提供了可以增加key-value對,和刪除key-value對的一系列方法
代碼演示
int main(int argc, const char * argv[]) {@autoreleasepool {NSMutableDictionary* dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"iOS", @"99", nil];dict[@"99"] = @"iOSS";[dict print];dict[@"Android"] = @"ddd";[dict print];NSDictionary* dict2 = [NSDictionary dictionaryWithObjectsAndKeys:@"Java", @"sss", @"python", @"struct", nil];[dict addEntriesFromDictionary:dict2];[dict print];[dict removeObjectForKey:@"sss"];[dict print];}return 0;
}
打印結果如下: