copy block KVC predicate 正则表达式
copy
对不可变的string,dictionary,array进行copy,是浅拷贝,相当于只是增加了引用计数
NSString *str0 = @"hello"; NSString *str01 = [str0 copy]; NSLog(@"str >>>> %@, %p", str0, str0); NSLog(@"str1 >>>> %@, %p", str01, str01); NSString *str1 = [[NSString alloc] initWithFormat:@"age%d",18]; NSString *str11 = [str1 copy]; // 浅拷贝 NSLog(@"str1 >>>> %@, %p", str1, str1); NSLog(@"str11 >>>> %@, %p", str11, str11);
对可变的string,dictionary,array进行copy, 是深拷贝,但是得到的新结果是不可变的对象,相当于内容快照
NSMutableString *str2 = [NSMutableString stringWithString:@"afternoon"]; [str2 appendString:@"hello"]; NSString *str21 = [str2 copy]; // NSMutableString经过copy之后得到的字符串是不可变的,这个copy是深拷贝 //[str21 appendString:@"hello"]; NSLog(@"str2 >>>> %@, %p", str2, str2); NSLog(@"str21 >>>> %@, %p", str21, str21);
字典的拷贝
// NSDictionary NSDictionary *dict1 = [NSDictionary dictionaryWithObjectsAndKeys:@"xiaoming",@"name",@"19",@"age", nil]; NSDictionary *dict11 = [dict1 copy]; NSLog(@"dict1 >>>> %@, %p", dict1, dict1); NSLog(@"dict11 >>>> %@, %p", dict11, dict11); // 浅拷贝 NSMutableDictionary *dict2 = [NSMutableDictionary dictionaryWithDictionary:dict1]; NSDictionary *dict21 = [dict2 copy]; NSLog(@"dict2 >>>> %@, %p", dict2, dict2); NSLog(@"dict21 >>>> %@, %p", dict21, dict21);//深拷贝
mutableCopy
对不可变的string,dictionary,array进行mutableCopy,是深拷贝,得到的新结果是可变的对象
对可变的string,dictionary,array进行mutableCopy,也是深拷贝,得到的新结果是可变的对象
拷贝的结果是否可变取决于拷贝的方法 * copy得到的是不可变的对象 * mutablecopy得到的是可变的对象
demo
NSArray *arr1 = [NSArray arrayWithObjects:@"xxx",@1,@3.14F,@'x',nil]; NSMutableArray *arr11 = [arr1 mutableCopy]; arr11[1] = @99999; NSLog(@"arr1 >>>> %@, %p", arr1, arr1); NSLog(@"arr11 >>>> %@, %p", arr11, arr11); NSMutableArray *arr111 = [arr11 mutableCopy]; arr111[1] = @11111111; NSLog(@"arr11 >>>> %@, %p", arr11, arr11); NSLog(@"arr111 >>>> %@, %p", arr111, arr111);
数组里只是存放的对象的地址,所以不管是copy还是mutablecopy都不会对数组里的元素对象产生改变
TestClass *t1 = [[TestClass alloc] initWithName:@"xiaoming"]; TestClass *t2 = [[TestClass alloc] initWithName:@"xiaoli"]; TestClass *t3 = [[TestClass alloc] initWithName:@"xiaohong"]; TestClass *t4 = [[TestClass alloc] initWithName:@"xiaolv"]; NSArray *st = @[t1, t2, t3, t4]; NSMutableArray *mtst = [st mutableCopy]; NSLog(@"st >>>> %p,%@", st, st); NSLog(@"mtst >> %p,%@", mtst, mtst); NSLog(@"st[0] >>> %p, %@", st[0], st[0]); NSLog(@"mtst[0] >>> %p, %@", mtst[0], mtst[0]);
代码块 block
代码块 void (*funcPtr)(void); //函数指针,声明代码块如下:
// void (*funcPtr)(void); //函数指针 void (^theBlock)(void) = ^(void){ printf("hello, qingyun\n"); NSLog(@"hello!"); };
有参数返回值的代码块的声明:
int (^add)(int,int) = ^(int a,int b){ return a+b; }; int result = add(3,5);
theBlock();//代码块的直接调用
typedef定义代码块的类型:定义的时候只需要关注参数类型和返回值类型
typedef int <returntype> (^代码类型的名字)(arg1,arg2...........);
typedef int (^mathBlock)(int,int); mathBlock add1 = ^(int a,int b){ return a+b; }; mathBlock sub1 = ^(int a,int b){ return a-b; }; // 这只是代码块的定义 mathBlock foo = ^(int a,int b){ printf("hello, qingyun %d\n", b); NSLog(@"hello %d!", a); return 0; }; // 调用代码块 foo(100,200);
代码块的内联用法解决冒泡排序,小在前,大在后
NSArray *students = @[@"yangxu",@"shuaifeng",@"liushuai",@"yuanao",@"sunpengtao"]; NSLog(@"students >>>> %@", students); NSArray *sortedSt = [students sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { return [obj1 compare:obj2]; }]; NSLog(@"sorted >>>>> %@", sortedSt); NSArray *ages = @[@20,@19,@31,@40]; NSArray *sortedAg = [ages sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { return [obj1 compare:obj2]; }]; NSLog(@"sorted >>>>> %@", sortedAg); NSArray *names = @[@"xdasfafe",@"sss",@"wefwfwafawfwafwaf",@"wewwew"]; NSArray *sortedNm = [names sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { if ([obj2 length] > [obj1 length]) { return NSOrderedAscending; } else if ([obj2 length] == [obj1 length]) { return NSOrderedSame; } else { return NSOrderedDescending; } }]; NSLog(@"sorted >>>>> %@", sortedNm);
代码块与变量:
局部变量在代码块中回当做常量来使用,不能更改否则会出错
int localVar = 9999; mathBlock bar = ^(int a, int b){ //localVar++; // 这个地方会报错,局部变量在代码块中会当做常量来使用 NSLog(@"localVar >>>> %d", localVar); // 局部变量在代码块中使用的时候在代码块定义时已经取到当时的值,跟调用局部变量的值无关 return 0; }; localVar = 1111111; bar(10, 100);
__block修饰过的局部变量在代码块中可以进行更改
__block int localVar = 9999; // __block修饰过的局部变量可以在代码块中进行更改 localVar++; mathBlock bar = ^(int a, int b){ localVar++; // NSLog(@"localVar >>>> %d", localVar); return 0; }; NSLog(@"localVal >>>> %d", localVar); bar(10, 100); NSLog(@"localVal >>>> %d", localVar);
静态变量和全局变量的值可以直接在代码块中修改
静态变量
static int localVar1 = 8888; mathBlock bar1 = ^(int a, int b){ localVar1++; // NSLog(@"localVar >>>> %d", localVar1); return 0; }; NSLog(@"localVal1 >>>> %d", localVar1); bar1(10, 100); NSLog(@"localVal1 >>>> %d", localVar1);
全局变量的声明在main函数之外
#import <Foundation/Foundation.h> #import "TestClass.h" int globalVar = 7777; int main(int argc, const char * argv[]) { @autoreleasepool {
数组的对象元素在代码块中,对象变量的值可以直接进行操作,但是数组名指针的值不能更改,否则会报错(局部变量的值不能在代码块中更改)
KVC
key value code
通过键和键路径访问代码,取值和设置值
NSDictionary *dict = @{ @"k1":@"v1", @"k2":@2, @"k3":@3.14f, @"k4":@{ @"k41":@"xingchen", @"age":@20 } }; NSMutableDictionary *dict1 = [NSMutableDictionary dictionaryWithDictionary:dict]; // 键和键路径 NSLog(@"k1 >>> %@ %@", [dict objectForKey:@"k1"], [dict valueForKey:@"k1"]); NSLog(@"k41 >>> %@", [dict valueForKeyPath:@"k4.k41"]); // 键路径,理论上键路径是没有层数限制的 [dict1 setValue:@21 forKey:@"k2"]; // 设置值的方法
KVC完成数据统计
NSCalendar *canlendar = [NSCalendar currentCalendar]; NSDateComponents *dc = [[NSDateComponents alloc] init]; Engineer *eg1 = [[Engineer alloc] init]; eg1.name = @"likai"; eg1.salary = 100000; dc.year = 2015; dc.month = 8; dc.day = 15; eg1.date = [canlendar dateFromComponents:dc]; Engineer *eg2 = [[Engineer alloc] init]; eg2.name = @"jiaxin"; eg2.salary = 1100010; dc.year = 2015; dc.month = 11; dc.day = 31; eg2.date = [canlendar dateFromComponents:dc]; Engineer *eg3 = [[Engineer alloc] init]; eg3.name = @"wenhai"; eg3.salary = 1100010; dc.year = 2015; dc.month = 10; dc.day = 31; eg3.date = [canlendar dateFromComponents:dc]; NSArray *egs = @[eg1, eg2, eg3]; // 快速运算 NSLog(@"avg >>>>> %@", [egs valueForKeyPath:@"@avg.salary"]);// 平均数 NSLog(@"latest >>>>> %@", [egs valueForKeyPath:@"@max.date"]);// 最大值 NSLog(@"min salary >>>>> %@", [egs valueForKeyPath:@"@min.salary"]);// 最小值 NSLog(@"count >>>> %@", [egs valueForKey:@"@count"]); // 求数目 NSLog(@"count >>>> %@", [egs valueForKeyPath:@"@sum.salary"]); //求工资总和 NSLog(@"工资水平 >> %@",[egs valueForKeyPath:@"@distinctUnionOfObjects.salary"]);// 求不同的结果集合
谓词NSPredicate
谓词用来对数据集合惊醒查找和筛选的工作
在进行查找和筛选的时候一般使用正则表达式
#import <Foundation/Foundation.h> // 谓词用来对数据集合进行查找和筛选的工作 // 在进行查找和筛选的时候一般要是使用正则表达式 int main(int argc, const char * argv[]) { @autoreleasepool { // 1.关系运算符在谓词中的使用 // < > >= <= == != NSArray *arr1 = @[@100,@10000,@999,@98,@3.14F]; NSPredicate *pred1 = [NSPredicate predicateWithFormat:@"SELF < 100"]; //谓词中的关键字可以使用大写来表示,来区分其他自定义的键名 NSArray *arr11 = [arr1 filteredArrayUsingPredicate:pred1]; NSLog(@"arr11 >>>> %@", arr11); // 使用谓词对数组进行过滤,得到的结果是符合条件的子元素的集合 NSArray *arr2 = @[@{ @"score":@99, @"name":@"guANgzhi", @"age":@20, @"money":@{@"thismonth":@11111, @"lastmonth":@100} }, @{ @"score":@101, @"name":@"yuanao", @"age":@18, @"money":@{@"thismonth":@10000, @"lastmonth":@100} }, @{ @"score":@50, @"name":@"llllafusong", @"age":@30, @"money":@{@"thismonth":@7777, @"lastmonth":@100} }, @{ @"score":@50, @"name":@"Bälle", @"age":@30, @"money":@{@"thismonth":@7777, @"lastmonth":@100} }, @{ @"score":@50, @"name":@"balle", @"age":@30, @"money":@{@"thismonth":@7777, @"lastmonth":@100} }, @{ @"score":@50, @"name":@"kalle", @"age":@30, @"money":@{@"thismonth":@7777, @"lastmonth":@100} } ]; NSPredicate *pred2 = [NSPredicate predicateWithFormat:@"MONEY.thismonth > 1000"]; NSLog(@"arr22 >>> %@", [arr2 filteredArrayUsingPredicate:pred2]); // 2.逻辑运算符 // &&(AND) ||(OR) NSPredicate *pred3 = [NSPredicate predicateWithFormat:@"age >= 18 AND money.thismonth <= 11000"]; NSLog(@"arr22 >>> %@", [arr2 filteredArrayUsingPredicate:pred3]); // 3.向谓词对象发消息,一般用来检验集合对象是否满足条件 // ALL 所有的元素都需要满足条件 NSPredicate *pred4 = [NSPredicate predicateWithFormat:@"ALL money.thismonth > 10"]; if ([pred4 evaluateWithObject:arr2]) { NSLog(@"符合条件"); } // ANY 只要有任意一个元素满足即可 NSPredicate *pred5 = [NSPredicate predicateWithFormat:@"ANY age > 18"]; if ([pred5 evaluateWithObject:arr2]) { NSLog(@"符合条件"); } // 4.范围查找 // IN BETWEEN NSPredicate *pred6 = [NSPredicate predicateWithFormat:@"age IN {20,30}"]; NSLog(@"arr22 >>> %@", [arr2 filteredArrayUsingPredicate:pred6]); // IN 在指定的几个数值范围 NSPredicate *pred7 = [NSPredicate predicateWithFormat:@"ALL age IN {18,20,30}"]; if ([pred7 evaluateWithObject:arr2]) { NSLog(@"符合条件"); } // BETWEEN在起始数值范围之内 NSPredicate *pred8 = [NSPredicate predicateWithFormat:@"ALL age BETWEEN {18,30}"]; if ([pred8 evaluateWithObject:arr2]) { NSLog(@"符合条件"); } // 5.谓词对字符串的操作 // BEGINSWITH ENDSWITH CONTAINS LIKE NSPredicate *pred9 = [NSPredicate predicateWithFormat:@"name BEGINSWITH 'fu'"]; NSLog(@"arr22 >>> %@", [arr2 filteredArrayUsingPredicate:pred9]); NSPredicate *pred10 = [NSPredicate predicateWithFormat:@"name ENDSWITH 'zhi'"]; NSLog(@"arr22 >>> %@", [arr2 filteredArrayUsingPredicate:pred10]); // [c]可以不区分大小写[d]不区分发音符号[cd] NSPredicate *pred11 = [NSPredicate predicateWithFormat:@"name CONTAINS[cd] 'ba'"]; NSLog(@"arr22 >>> %@", [arr2 filteredArrayUsingPredicate:pred11]); // LIKE 和 通配符 // ?代表任意一个字符 *代表任意多个字符 NSPredicate *pred12 = [NSPredicate predicateWithFormat:@"name LIKE[c] '??a*'"]; NSLog(@"arr22 >>> %@", [arr2 filteredArrayUsingPredicate:pred12]); // 6.谓词模板 // 6.1 格式化 %K 代表格式化键名 值的格式化需要使用对象,所以20不能直接使用,需要使用@20这个NSNUmber NSString *key1111 = @"age"; NSNumber *value1222 = @30; NSPredicate *pred13 = [NSPredicate predicateWithFormat:@"%K >= %@", key1111, value1222]; NSLog(@"arr22 >>> %@", [arr2 filteredArrayUsingPredicate:pred13]); // 6.2 批量格式化 NSPredicate *predTheme = [NSPredicate predicateWithFormat:@"age >= $age AND money.thismonth >= $money AND score <= $score"];// predTheme是一个谓词对象,但是只是一个模板,没有真实地使用意义 // 用谓词模板来创造一个真正可以使用的谓词对象predicateWithSubstitutionVariables:方法是有返回值的,返回值就是可以使用的谓词对象 NSPredicate *pred14 = [predTheme predicateWithSubstitutionVariables:@{@"age":@20,@"money":@7776,@"score":@60}]; NSLog(@"---------------"); NSLog(@"arr22 >>> %@", [arr2 filteredArrayUsingPredicate:pred14]); // 7 谓词与正则表达式 NSString *emailTest = @"[A-Z0-9a-z%_]+@[A-Z0-9a-z]+\\.[A-Za-z]{2,4}"; //zHqin8pei8@163qq .com NSPredicate *pred15 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailTest]; NSString *email1 = @"zhqin%pe1_23afeaw12313efw12313aefawfawf@1adqwqas63.c"; NSString *email2 = @"260208611@qq.com"; NSString *email3 = @"260208611com"; // 判断是否匹配表达式 if ([pred15 evaluateWithObject:email1]) { NSLog(@"email1是有效的邮箱"); } if ([pred15 evaluateWithObject:email2]) { NSLog(@"email2是有效的邮箱"); } if ([pred15 evaluateWithObject:email3]) { NSLog(@"email3是有效的邮箱"); } NSString *testChar = @"[0-9a-zA-z_]"; NSString *exstr = @"9"; NSPredicate *pred16 = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", testChar]; if ([pred16 evaluateWithObject:exstr]) { NSLog(@"shi0-9a-zA-z_"); } // 利用正则表达式来获取子字符串 NSString *testEmail = @"fajweofjwaofjwaof,wjefowafowaf,123123@163.com,fawewaf,feowafawf@awefawf.me"; NSRange range = [testEmail rangeOfString:emailTest options:NSRegularExpressionSearch]; if (range.location != NSNotFound) { NSLog(@"e1 >>>> %@", [testEmail substringWithRange:range]); } else { NSLog(@"没有找到。。。。"); } } return 0; }
浙公网安备 33010602011771号