OC基础知识点
补充:
1、所有可变的集合才能添加元素(不可变数组能添加元素)
2、id类型就是对象
3、方法需要传递多个参数时,参数以冒号分隔
4、 逗号运算符:优先级最低,低于赋值运算符,计算时,执行最后一个表达式的值
sson1 类之间的方法调用 | |
知识点1 | @public声明成员变量,此时成员变量属性为公共性, |
知识点2 | 成员声明方式最好采用:NSString *_name,为后期使用养成好习惯 |
知识点3 | 类方法: +(返回类型)方法名:(变量类型)变量名 对象方法: —(返回类型)方法名:(变量类型)变量名 |
知识点4 | 为成员变量赋值与使用方法:类名->成员变量 |
| Lesson2 可见度与方法 |
知识点1 | 除了@public声明成员变量,在编程过程中一般不使用公开类型,成员变量默认类型为Protect,在本类中可以选用private,仅供自己调用 |
知识点2 | 为成员变量设置get方法与set方法 //- (void)setName:(NSString *)name; - (NSString *)getName; 多参数声明方法:- (void)setName:(NSString *)name Sex:(NSString *)sex Age:(NSInteger)age; |
知识点3 | @class+ 类名;完成类的声明,成员变量可以设置成类名+成员名 ,方便完成类与类之间的方法调用 |
知识点4 | 初始化方法:- (id)initWithName:(NSString*)name Sex:(NSString*)sex Age:(NSInteger)age; |
Lesson3 继承初始化 | |
继承的五个特点: | 1、子类继承父类的实例变量与方法 2、继承具有单向性(父类不能有子类特征和行为) 3、oc里没有多继承(能间接继承多个父类) 4、继承具有传递性 5、如果子类不满意父类的方法,可以进行重写父类方法(不需要声明) |
@class与#include与#import的区别 | #include 的引入头文件是通过copy完成,#import的引入头文件也是通过copy完成,但是能解决重复引入问题, @class能解决import循环引入的问题 #include <>格式:引用标准库头文件(系统文件),编译器从标准库目录开始搜索, #incluce ""格式:引用非标准库的头文件,编译器从用户的工作目录开始搜索,如果文件名用一对引号括起来则表明该文件是用户提供的头文件, |
知识点1:初始化方法实现 | #pragma mark 初始化方法1 (指定初始化方法) //通常把初始化方法中参数最全的作为指定初始化方法 - (id)initWithName:(NSString*)name andAge:(NSString*)age andSex:(NSString*)sex { self = [super init]; //调用父类的方法用super if(self) //判断父类(ISA指针)是否初始化成功,如果不成功子类就不用初始化了 { _name = name;_ sex = sex;_ age = age; } return self; } |
知识点2:初始化方法2 | #pragma mark 初始化方法2 (初始值为name,sex) - (id)initWithName:(NSString*)name andSex:(NSString*)sex { self = [self initWithName:name andAge:nil andSex:sex]; //调用本类的方法用self return self; } |
知识点3: 重写类的description方法 | - (NSString*)description //NSObject的方法,此处为重写 { return [NSString stringWithFormat:@"name = %@ ,sex =%@,age = %@",_name,_sex,_age]; } |
知识点4:便利构造器1 | + (id)personWithName:(NSString*)name andSex:(NSString*)sex andAge:(NSString*)age (person为小写的类名) { Person *person = [[Person alloc] initWithName:name andAge:age andSex:sex]; return person; //之所以能返回指针是因为指针存放在堆中(alloc),存放在栈中的东西是不能返回指针的 //类方法里面绝对不能使用实例对象 } #pragma mark 便利构造器2 + (id)personWithName:(NSString*)name { Person *person = [[Person alloc] initWithName:name andAge:nil andSex:nil]; return person; //之所以能返回指针是因为指针存放在堆中(alloc),存放在栈中的东西是不能返回指针的 }
|
| OcLesson4 Foundation |
知识点1:
NSString | 第一部分: 创建字符串 //第一种方法:不可变的字符串,也是最简单的 NSString *str1 = @"I love you"; //NSString 是苹果创建好的类 //第2种方法:(很重要,可以带多个参数) NSString *str2 = [[NSString alloc]initWithFormat:@"%@,%@",@"aaa",@"bbbb"]; //第3种方法: 不常用的,麻烦 NSString *str3= [[NSString alloc] initWithString:str1]; //第四种方法:这种方法不常见,没有赋值 // NSString *str4 = [NSString new]; /***************** 用类方法创建字符串 *******************/ // NSString *str5 = [NSString stringWithFormat:@"Anrai"]; NSString *str5 = [NSString stringWithFormat:@"%@,%@",@"nihao",@" dou"]; //指针重指向 // str6 = [str6 capitalizedString]; // 1、更改首字母为大写 // str6 = [str6 uppercaseString]; //2、字符串全大写 // str6 = [str6 lowercaseString]; //3、字符串全小写 //4、获取固定的字串 NSRange range = NSMakeRange(6, 3);//第一个数字是位置,第二个是长度 NSString *sub = [str6 substringWithRange:range]; //5、获取首尾的字串 NSString *sub_tou = [str6 substringToIndex:5]; //获取头部子串 NSString *sub_wei = [str6 substringFromIndex:10];//获取尾部子串 //6、字符串拼接 NSString *appendString = [sub_tou stringByAppendingString:sub_wei]; //7、插入字符串(替换字符串) NSRange range1 = NSMakeRange(0, 0); NSString *insertString = [str6 stringByReplacingCharactersInRange:range1withString:@"Say "]; //8、求字符串长度 NSUInteger len = [str6 length]; //9、字符串和基本类型的转化,要求转化的字符串只能为数字串和“.” NSString *numberString = @"3941898.5"; float number = [numberString floatValue]; // 方法名 :[str xxValue ]; //10、获取单个字符 unichar ch = [str6 characterAtIndex:3]; //获取从坐标0开始 //11、获取子字符串在字符串中的位置与长度 NSString *str7 = @"shi"; NSRange range2 = [str6 rangeOfString:str7]; //子字符串在后面,原字符串在前 NSLog(@"%@",NSStringFromRange(range2)); //12、替换字符串 NSString *opeString = @"beijing150516"; //15替换为14 opeString = [opeString stringByReplacingOccurrencesOfString:@"15"withString:@"14"]; //前旧后新,不可变字符串返回值为指针类型,需要接受后才能输出 //13、删除字符串(不可变字符串没有直接删除的方法,需要执行替换操作实现) NSString * removeString = [opeString stringByReplacingOccurrencesOfString:@"beijing" withString:@""]; //14、根据文件去创建字符串 NSString * contentString = [[NSString alloc]initWithContentsOfFile:@"/Users/lanou3g/Desktop/page.txt" encoding:NSUTF8StringEncoding error:nil]; //15、汉字转化为拼音 NSString *str = @"sir, 我 是 li ming"; NSString *pinyin = [ChineseToPinyin pinyinFromChiniseString:str]; NSLog(@"转化 :%@",pinyin); //大写形式 NSArray *array1 = [pinyin componentsSeparatedByString:@" "];//通过空格分隔字符串 NSLog(@"数组转化 :%@",array1); NSString *ss_last = [pinyin substringFromIndex:4];//从第几个位子开始取剩余的字母 NSString *ss_before = [pinyin substringToIndex:1];//取首字母 //16、字符串写入到文件,与导出文件 /****** 字符串的导出 **********/ NSString *str4 = @"asdfasdfasd发个还是"; NSString *path11 = @"/Users/lanou3g/Desktop/222.txt"; NSError *error2; [str4 writeToFile:path11 atomically:YES encoding:NSUTF8StringEncodingerror:&error2]; //字符串写入到文件中 if(error2) { NSLog(@"chucuo %@",[error2 localizedDescription]); //会返回主要的错误信息 } else { NSString *arr = [ NSString stringWithContentsOfFile:path11encoding:NSUTF8StringEncoding error:nil]; //字符串读取 NSLog(@"-path11-----arr:%@",arr); NSLog(@"success"); } //字符串遍历 /********* 数组的遍历有四种方法: for --- for in ---- block ---迭代器( NSEnumerator) *************/ NSArray *array3 = [NSArray arrayWithObjects:@"11",@"22",@"33", nil]; NSEnumerator *enumerator = [array3 objectEnumerator]; //获取迭代器 NSEnumerator *enumerator1 = [array3 reverseObjectEnumerator]; //获取反序的迭代器,从尾部开始遍历 id obj = nil; while (obj = [enumerator nextObject]) { NSLog(@"%@",obj); } //正序遍历 while (obj = [enumerator1 nextObject]) { NSLog(@"%@",obj); } //反序遍历 |
知识点2:NSMutableString | NSMutableString *mutableString1 = [[NSMutableString alloc]initWithFormat:@"%@%@",@"ni",@"hao"]; NSLog(@"可变字符串:%@",mutableString1); //1、可变的字符串,对于他的修改,实质就是对于自身的修改 //可变字符串的操作方法 1、拼接 [mutableString1 appendString:@"Love"]; NSLog(@"拼接:%@",mutableString1); //2、子字符串替换 // NSRange range3 = NSMakeRange(0, [mutableString1 length]); //第三个参数搜索的方式,第四个参数:搜索的范围 // [mutableString1 replaceOccurrencesOfString:@"Love" withString:@"Sir" options:NSCaseInsensitiveSearch range:range3]; [mutableString1 replaceCharactersInRange:NSMakeRange(5, 4)withString:@" Sir"];//整个字符串替换 NSLog(@"可变字符串替换%@",mutableString1); |
知识点3:
NSArray
| /**************************** 第三个内容: NSArray(数组)的特点:1、可以存放不同类型的数据 2、oc中的数组,其数据必须是对象 3、oc中数组能直接参加运算 4、数组是有序的 *************************************/ Person *person1 = [[Person alloc] initWithName:@"zhangsan"]; Person *person2 = [[Person alloc] initWithName:@"lisi"]; //四种方法去创建 NSArray *array11 =@[person1,person2,@"lisi电视剧"];//语法糖 NSArray *array12 = [[NSArray alloc]initWithObjects:person1,person2, nil]; //使用alloc init方法去创建 NSArray *array13 = [NSArrayarrayWithObjects:person1,person2, nil]; //类方法 NSArray *array14 = [[NSArray alloc]initWithArray:array1]; //根据数组创建另一个数组 //打印数组的三种方式 NSLog(@"一%@",array1);//第一种:打印汉字时不能正常显示 for(int i = 0; i < 3; i++) { NSLog(@"二%@",array1[i]);//语法糖,第二种打印方式 } //第三种打印:oc中的循环遍历 for (id objectin array1) { NSLog(@"三%@",object); } for (Person *objectin array12) { NSLog(@"%@",object); } //创作数组的方法 //1、求数组里面元素的个数 NSUInteger array3count = [array3count]; NSLog(@"数组1的元素个数:%lu",array3count); //2、删除元素 ---(不可变数组没有删除元素的方法) //3、添加元素 array3 = [array3 arrayByAddingObject:@"liuhui"]; //第三种打印:oc中的循环遍历 for (id objectin array3) { NSLog(@"三%@",object); } //4、获取数组里面第一个元素 Person *temp = [array1 firstObject]; NSLog(@"第一个元素%@",temp); //5、获取数组里面最后一个元素 NSString *string = [array1 lastObject]; NSLog(@"最后一个元素%@",string); //6、判断数组里面是否包含某个元素 BOOL result = [array1 containsObject:person2]; //6、判断数组里面是否包含某个元素 NSLog(@"%d",result); //%g 打印有效位数 //7、判断一个元素到底在哪一个位置 NSUInteger index = [array1indexOfObject:person2]; //坐标位置 NSLog(@"%lu",index); |
知识点4: NSMutableArray
| /*第四个内容: NSMutableArray ****************/ NSMutableArray *mutableArray = [[NSMutableArray alloc] init]; [mutableArray addObject:person1]; [mutableArray addObject:person2]; NSLog(@"mutableArray个数:%lu",[mutableArraycount]); //删除元素 Person *person3 = [[Person alloc]initWithName:@"huang"]; [mutableArray addObject:person3]; // NSArray *array = @[person2,person3]; // [mutableArray removeObjectsInArray:array];//批量删除 // [mutableArray removeAllObjects];//全部删除 // [mutableArray removeLastObject];//删除最后一个元素 // [mutableArray exchangeObjectAtIndex:0withObjectAtIndex:2];//交换两个元素 NSArray *arr1 = @[person1]; NSArray *arr2 = @[person2]; NSArray *arr3 = @[person3]; NSArray *arr = @[arr1,arr2,arr3]; for (id object in arr) { NSLog(@"%@",object); } |
知识点5:
NSNumber 是更具体的包装类,主要方法有三种: + numberWithXxx
-initWithXxx类型封装
- xxxValue 格式转换
| /*** 第五个内容: NSNumber *************/ //NSNumber ,封装基本类型,使其变为对象类型 NSNumber *number1 = [[NSNumber alloc]initWithInt:2]; NSArray *arr4 = @[number1]; NSNumber *resultNumber = arr4[0]; int result1 = [resultNumberintValue]; NSLog(@"result = %d",result1); //第二种方法实现 NSArray *arr5 = @[@(1),@(2),@(3)]; //语法糖 int result2[3]; for (int i =0; i < 3; i++) { NSNumber *resultNumber = arr5[i]; result2[i] = [resultNumber intValue]; NSLog(@"result%d =%d",i,result2[i]); } |
知识点6: NSValue是NSNumber的父类
| /*** 第六个内容 : NSValue *******/ NSRange range11 = NSMakeRange(2,5); NSValue *value = [NSValue valueWithRange:range11];//便利构造器 |
知识点7: 查阅API文档 | (1)Window->Documentation and API->select (2)Alt + 关键字有 " ?"后 + reference (3)编程界面中右边框中有Quick Help ,鼠标移动到关键字上即可查询 more related详细:继承的父类、遵守的协议、框架framework、适用环境、声明地点、 (!!!!后两个较为重要) 相关的文档中会有解释、示例代码(sample code)
|
知识点8:NSDictionary | NSDictionary (字典:包含键(key)与值(value)且一一对应)特点: (1)只能存对象 (2)字典是无序的 (3)key值是不可以重复的,如果重复程序会自动保留第一对键值对 ---(对可变字典不成立) (4)value值可以重复 (5)key值与value值必须是对象 (6)一般情况key值使用字符串 NSDictionary *dict = [[NSDictionary alloc]initWithObjectsAndKeys:@"hao",@"111",@"ren",@"222",nil];//输出顺序key值在前 NSDictionary *dict1 =[NSDictionarydictionaryWithObjectsAndKeys:@"123",@"1",@"456",@"4",nil]; NSDictionary *dict2 = [NSDictionarydictionaryWithObject:@"value1"forKey:@"key1"];//不常用 NSDictionary *dict3 =@{@"a3":@"value3",@"z1":@"value1",@"k2":@"value1"}; //重点 NSLog(@"111%@",dict); NSLog(@"222%@",dict1); NSLog(@"333%@",dict2); NSLog(@"444%@",dict3); // 字典是无序的 NSInteger dictCount = [dict3 count];//1、字典的键值对计数方法 NSLog(@"计数%lu",dictCount); NSArray *keys = [dict3 allKeys];//2、拿出字典所有的key值 NSLog(@"dict3中的key值:%@",keys); NSArray *values = [dict3 allValues];//3、拿出字典中所有的value值 NSLog(@"dict3中的value值:%@",values); Person *person1 = [[Person alloc] initWithName:@"zhangsan"]; Person *person2 = [[Person alloc] initWithName:@"lisi"]; NSDictionary *finalDic = @{@"key1":person1,@"key2":person2};// 存放对象 NSLog(@"%@",finalDic); [dict3 objectForKey:@"k2"];// 4、拿出某一个value值,字典的方法---objectForKey NSString *value = dict3[@"k2"];//语法糖实现 NSLog(@"拿出某一个value值:%@",value); //根据value拿出某些个key值 NSArray *keys2 = [dict3 allKeysForObject:@"value1"]; NSLog(@"根据value拿出某些个key值%@",keys2); //6、遍历字典--value值 for (id objectin dict3) { NSLog(@"遍历字典%@",dict3[object]); } //局限性 /************** 第二种遍历方式 *************/ NSArray *keyArray = [dict3 allKeys]; for (NSString *keyin keyArray) { NSLog(@"%@",dict3[key]); } 字典的其他使用: 1、数组与字典可以相互嵌套 2、如果字典里面去放数组,一般情况把数组作为value值 |
知识点9:
NSMutableDictionary 可变数组 | // NSMutableDictionary *mutableDic = [[NSMutableDictionary alloc]initWithCapacity:10];//一次性开辟10个空间 NSMutableDictionary *mutableDic1 = [NSMutableDictionary dictionary];//继承不可变字典 [mutableDic1 setObject:person1 forKey:@"key3"];//1、往可变的字典里面添加元素 [mutableDic1 setObject:person2 forKey:@"key4"]; [mutableDic1 setObject:person2 forKey:@"key3"]; NSLog(@"mutableDic1键值对个数:%lu",[mutableDic1 count]); NSLog(@"%@",mutableDic1); //如果可变字典key值重复,则会保留最后一个key值对应的键值对 //2、删除字典里面的元素 // [mutableDic1 removeAllObjects];//删除字典里所有元素 // NSLog(@"删除全部:%@",mutableDic1); //删除某个值 // [mutableDic1 removeObjectForKey:@"key3"]; // NSLog(@"删除某个值:%@",mutableDic1); NSArray *delectArray =@[@"key3",@"key4"]; [mutableDic1 removeObjectsForKeys:delectArray]; NSLog(@"删除值:%@",mutableDic1); |
知识点 10 : NSSet |
NSset可以存放任何数据类型的对象,不是数据,它是无序的,集合内不能存不同类型的对象 NSSet *set = [NSSet setWithObjects:@"you",@"are",@"boy",nil]; NSLog(@"%@",set); //把数组中的元素放到set中(以下三行代码去除重复元素) NSArray *arraySet =@[@"1",@"2",@"1"]; NSSet *set1 = [NSSet setWithArray:arraySet]; //操作set方法 NSLog(@"set元素个数:%lu",set1.count);//统计set中元素的个数 NSLog(@"set所有元素:%@",set1.allObjects);//取出集合中所有元素 NSLog(@"set某个元素:%@",[set1 anyObject]);//取出集合中某个元素,不保证随机性 NSLog(@"%d", [set1 intersectsSet:set]);//取交集,返回值BOOL类型 |
知识点 11 : NSMutableSet | NSMutableSet *set2 = [NSMutableSet setWithObjects:@"1",@"2",@"3",nil]; NSMutableSet *set3 = [NSMutableSet setWithObjects:@"4",@"2",@"3",nil]; NSLog(@"%d", [set2intersectsSet:set3]);//取交集,返回值BOOL类型 [set2 unionSet:set3];//取并集,返回值void类型 [set2 minusSet:set3];//取差集,返回值void类型 [set2 removeAllObjects];//删除集合所有元素 |
知识点 11 : NSCountedSet | NSCountedSet *countSet = [NSCountedSetsetWithObjects:@"5",@"3",@"6",@"3",nil]; //输出对应元素的个数 NSLog(@"%@",countSet); |
| Lesson6 protocol(协议只是一个头文件,分为正式与非正式两种) | ||
正式协议:
遵守协议的才是代理 | 这种协议为正式协议注意:oc中虽然没有多继承,但是一个类能遵守多个协议,这样间接的实现了多继承 @protocol MarryProtocol <NSObject> @required //默认是@required必须实现的 #pragma mark 协议一:赚钱 - (void)makeMoney; @optional //可以选择性实现 - (void)lookAfterBady; @end @interface Boy : NSObject<MarryProtocol> //遵守协议 @interface Girl :NSObject { NSString *_name; id<MarryProtocol>_delegate;//代理声明的变量 } #pragma mark setter方法(给代理赋值) -(void)setDelegate:(id<MarryProtocol>)delegate; - [girl setDelegate:boy];//女孩把男孩作为自己的代理 | ||
非正式协议 | //非正式协议,在别的类中声明 @protocol informalityProtocol <NSObject> - (void)makeMoney1; @end @interface Person :NSObject @end | ||
| 使用数组完成通讯录的制作 | ||
过程 | 1、//定义一个可变的数组,存放联系人 NSMutableArray *contactArray = [NSMutableArrayarray]; //最外层通讯录数组 2、//大数组放26个小数组 for(int i =0; i< 26; i++) //第二层 26个数组的创建 { NSMutableArray *array1 = [NSMutableArrayarray]; [contactArray addObject:array1]; } 3、//添加联系人 NSMutableArray *groupArray0 = [contactArrayobjectAtIndex:0];//1、拿到对应的分组 [groupArray0 addObject: p0];//2、往对应分组添加联系人 4、//9、展示通讯录中所有联系人 for (NSMutableArray *arrayin contactArray) { for (Person *personin array) { NSLog(@"%@",person); } } 5、按照条件显示联系人信息 for (NSMutableArray *arrayin contactArray) { for (Person *personin array) { if ([[person3 getGroupName] isEqualToString:@"a"]) //获得a组的所有联系人信息 if ([[person4 getPhoneNumber] isEqualToString:@"1686891"]) 4、根据电话号码搜索联系⼈ if ([[person2 getSex] isEqualToString:@"女"])//5、获取所有女性联系⼈ NSLog(@"%@",person); } } //6、根据姓名删除联系⼈(在for-in循环里不能直接删除,否则可能会引起崩溃) NSMutableArray *opeArray; NSMutableArray *delectNameArray = [NSMutableArrayarray] ; for (NSMutableArray *array3in contactArray) { for (Person *person3in array3) {
if ([[person3getName] isEqualToString:@"赵信z"]) { opeArray = array3; [delectNameArrayaddObject:person3]; // [array3 removeObject:person3]; //(在for-in循环里不能直接删除,否则可能会引起崩溃) } } } //统一删除 [opeArray removeObjectsInArray:delectNameArray]; 7、删除某个分组全部联系⼈ NSMutableArray *delectArray = contactArray[25]; [delectArray removeObject:p5]; //删除Z组中的某个联系人 [delectArray removeAllObjects]; //删除Z组中的所有联系人
| ||
使用字典完成通讯录的制作 | |||
通讯录 初始化方法 | #pragma mark 通讯录初始化方法 - (id)initWithContactName:(NSString*)name { self = [superinit]; if(self) { _contactName = name; _contactDic = [NSMutableDictionarydictionary ];//对通讯录进行初始化 } returnself; } | ||
创建通讯录管理类 | ContactManager *manager = [[ContactManageralloc]initWithContactName:@"mac通讯录"]; //往通讯录里存储联系人 [manager addContactWithPerson:p0]; | ||
获取姓名首字母 | #pragma mark 获取姓名首字母 - (NSString*)getFirstAlbumOfName:(NSString*)name { NSString *pinyin = [ChineseToPinyinpinyinFromChiniseString:name]; NSString *name_tou = [pinyinsubstringToIndex:1]; //获取姓名首字母,默认大写的 // NSLog(@"%@",[group lowercaseString]); //3、字符串全小写 return name_tou; } | ||
添加联系人的方法 | #pragma mark 添加联系人的方法 - (BOOL)addContactWithPerson:(Person*)person { if ([persongetName].length <1 || [person getName] == nil || [[persongetName] isKindOfClass:[NSNullclass]]) { returnNO; } //首先判断通讯录里面有没有对应的分组 NSString *group = [selfgetFirstAlbumOfName:[persongetName]];//获取姓名首字母 NSArray *keyArray = [_contactDicallKeys]; //拿到字典里面所有的key值,即为分组的名字 //判断所有分组的数组是否包含此联系人应该在的分组 if ([keyArraycontainsObject:group]) { //包含的情况 NSMutableArray *valueArray = [_contactDicobjectForKey:group]; //根据key找到对应的value数组 [valueArray addObject:person]; returnYES; } else {//不包含的情况 NSMutableArray *valueArray = [NSMutableArrayarray]; //没有对应的数组就需要创建 //先把联系人放到这个数组 [valueArray addObject:person]; //把数组放到字典中 [_contactDicsetObject:valueArrayforKey:group]; returnYES; } returnNO; } | ||
展示所有联系人 | NSArray *keysArray = [_contactDicallKeys];//拿出所有分组名 keysArray = [keysArray sortedArrayUsingSelector:@selector(compare:)]; //a-z 排序,compare是选择器 //遍历分组名数组 for (NSString *keyin keysArray) { NSMutableArray *valueArray = [_contactDicobjectForKey:key]; //拿出分组名对应的信息 NSLog(@"----%@-----",key); for (Person *pin valueArray) { NSLog(@"%@",p); } } | ||
删除联系人 | - (BOOL)deleteContactWithPerson:(Person*)person { NSString *group = [selfgetFirstAlbumOfName:[persongetName]]; NSMutableArray *array = [_contactDicobjectForKey:group]; [array removeObject:person]; //先删除这个联系人 if(array.count <1)//如果分组里面没有其他联系人的时候,把整个分组删除掉 { [_contactDicremoveObjectForKey:group]; } returnYES; } | ||
按照性别搜索全部的女性联系人 | - (void)searchContactBySex:(NSString*)sex { NSArray *keysArray = [_contactDicallKeys]; for (NSString *keyin keysArray) { NSMutableArray *array =_contactDic[key];//语法糖 for (Person *pin array) { if ([[pgetSex]isEqualToString:sex]) { NSLog(@"%@",p); } } } } | ||
按照号码 搜索全部的联系人 | - (void)searchContactByPhoneNumber:(NSString*)phoneNumber { NSArray *keysArray = [_contactDicallKeys]; for (NSString *keyin keysArray) { NSMutableArray *array =_contactDic[key];//语法糖 for (Person *pin array) { if ([[pgetPhoneNumber]isEqualToString:phoneNumber]) { NSLog(@"%@",p); } } } } |
Lesson7 Block | |
纠正知识点1: | int array[10];的类型是int[10] ,函数是array——>结论:函数类型有无数个 |
纠正知识点2: | aa() //默认返回为整形类型 |
block之局部变量
| // 内存分类 :堆区(存指针) 栈区(系统自己管理) 常量区:程序结束后释放 静态区(全局区)代码区, 全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束释放。 //block里面局部变量的使用,block中引用局部变量是一个拷贝过程,拷贝之后变为一个常量,此时block的存储区域为栈区 代码: 代码区存放函数体的二进制代码 { int b; //栈 |
block之全局变量
| __block int number = 10; //__block 作用声明定义的变量在block中作为常量被使用, (如果在block中要修改局部变量,这需要使用__block声明定义的局部变量) void (^myBlock)(int x) = ^void(int x); //右边的返回类型不能丢 |
block之实现 | //3、block的实现部分,返回值最好加上实现部分的返回值类型 NSInteger (^block)(NSInteger x, NSInteger y) = ^NSInteger( NSInteger x, NSInteger y); NSArray *(^aBlock)(NSString * str,NSString *str2);NSString *(^aBlock)(NSString * str,NSString *str2); 实现:aBlock = ^( NSString * str,NSString *str2){ return str1; } 调用:aBlock(@"string1" @"string2"); |
block之排序 (练习compare 的使用方法,不可变数组使用)
| personArray = [personArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { //下面不是强制类型转换,相当于类型声明 //不可变数组使用 sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) Person *personObj1 = (Person*)obj1; Person *personObj2 = (Person*)obj2; if([[personObj1 getName] compare:[personObj2 getName]] > 0){ NSLog(@"%ld",(long)NSOrderedDescending); return NSOrderedDescending; // +1 }else if([[personObj1 getName] compare:[personObj2 getName]] < 0){ // NSLog(@"%ld",(long)NSOrderedAscending); return NSOrderedAscending; // -1 }else{ NSLog(@"%ld",(long)NSOrderedSame); return NSOrderedSame; // 0 } } ]; |
block之排序 (练习compare 的使用方法,可变数组使用)
| NSMutableArray *personMutableArray = [NSMutableArray arrayWithObjects:p1,p2,p3,p4, nil]; [personMutableArray sortUsingComparator:^NSComparisonResult(id obj1, id obj2) { //下面不是强制类型转换,相当于类型声明 //可变数组使用 sortUsingComparator:^NSComparisonResult(id obj1, id obj2) Person *personObj1 = (Person*)obj1; Person *personObj2 = (Person*)obj2; |
Compare 的使用
| 主要适用于字符串与数字的比较 链接:http://zcw-java.iteye.com/blog/1886817 NSCaseInsensitiveSearch 忽略大小写的比较字符串 NSNumericSearch 比较字符串的个数 NSLiteralSearch 区分大小写,进行完全比较 |
内存 | 最大的栈空间为 1M 内存的%80都被分为堆区 |
| Lesson8_Category |
知识点1:
宏定义 比较大小
| #define MAXValue1(A,B) A > B ? A : B //第一版本 3>2?3:2>5? 3>2?3:2:5 #define MAXValue2(A,B) (A) > (B) ? (A) : (B)//第二版本 #define MAXValue3(A,B) ((A) > (B) ? (A) : (B))//第三版本 #define MAXValue4(A,B) ({int __a = (A);int __b = (B); __a > __b ? __a : __b;})//第四版本 #define MAXValue5(A,B) ({__typeof(A)__a = (A);__typeof(B)__b = (B); __a > __b ? __a : __b;})//第五版本,不受类型限制 int result1 =MAXValue1(3 >2 ? 3 :2, 5); //第一个版本:套用三目运算符词性检测 NSLog(@"result1 = %i",result1); // 第二个版本的问题 int result2 =2 * MAXValue2(3,5); NSLog(@"result2 = %i",result2); //在没有大括号的时候,外围的运算会提前加入,导致运算出错 //第三个版本的问题 int a =11, b = 10; int result3 =MAXValue3(a++, b); NSLog(@"result3 = %i",result3); //如果++参与两次运算 则会出现错误 //第四个版本的问题,针对整形类型 int aa =6, bb = 10; int result4 =MAXValue4(aa++, bb); NSLog(@"result4 = %i",result4); //第五个版本的问题,广泛版本 float c =6, d = 10; float result5 =MAXValue5(c++, d); NSLog(@"result5 = %f",result5); |
Category 知识点 |
Category (类目、类别、分类)主要用来给没有源代码的类添加方法 如果Category里面写了跟原始类同名的方法,若是实例方法(-),则外面使用的时候是原始类的方法,如果这个方法是类方法(+),则外面使用的是category的方法类目:给原始类添加方法,子类可以继承这个方法 类目:为已知的类增加新的方法;延展:通知在本类的定义里使用类目来声明私有方法;协议:协议声明了可以被任何类实现的方法。 1)声明类目 局限性1:无法向类中添加新的实例变量。类别没有位置容纳实例变量。 局限性2:名称冲突,即类别中得方法与现有的方法重名。当发生名称冲突时,类别具有更高的优先级。你的类别方法将完全取代初始方法,从而无法再使用初始方法。有些编程人员在自己的类别方法中增加一个前缀,以确保不发生名称冲突。 3)类目的作用:cocoa中得类别主要用于3个目的: 第一,将类的实现分散到不同文件或者不同框架中。第二,创建对私有方法的前向引用。第三,向对象添加非正式协议。 |
延展:extension | 延展:extension 类名+() 作用:管理私有变量和私有方法 OC 中没有真正的私有变量和私有方法 @interfaceTeacher() - (void)showMypay; //只能够自己使用 @propertyNSString *pay; //私有类型 @end - (void)printPay { Teacher *tea = [[Teacheralloc]init]; tea.pay = @"200"; [tea showMypay]; //只能由展延类的对象个人使用,不能超出本.m文件 } |
Lesson10_delegate_block | |
非正式协议 | @protocol boyDelegate<NSObject> //非正式协议 - (void)washClothes; @end
@interface Boy : NSObject @(nonatomic,assign)id<boyDelegate>delegate; //用retain会造成循环引用代理要用assign - (void)clothesDirty; - (void)setDelegate:(id<boyDelegate>)delegate;
@end |
Block 方法的使用 | typedef void(^MYBLOCK)(void); //@class Boy; @interface Girl : NSObject //<boyDelegate> @property (nonatomic,retain)Boy *boyFriend; @property (nonatomic,copy)MYBLOCK block; //只写一个block是在栈区,用copy后就放到堆区了 - (void)test; @end |
| Lesson9_Memory |
内存方法 谨记 | oc 中的内存方法:MRC(Mannul Reference Counting,手动引用计数管理),automatic reference counting(ARC,自动引用计数管理),garbage collection(垃圾回收机制) iOS中内存方法: ARC:Xcode会帮助管理内存 MRC:需要开发人员手动去控制应用计数,一块内存区域引用计数一旦变为0,系统会自动将其删除。ios里面的关键字有 alloc 、retain、release、autorelease、copy,其中alloc的作用开辟内存引用从0变为1,retain的作用引用计数进行加1操作,release的作用多内存引用计数立刻进行减1操作,autorelease是对内存引用计数在未来的某个时间进行减1操作。copy的作用是把原来内存的内容(或是一个对象)拷贝到新的内存区域,原来内存区域的引用计数不变,新的区域引用计数由0变为1 Java 中的内存管理为:garbage collection (垃圾回收机制) |
| NSString *name = [[NSString alloc]initWithString:@"haha"]; //确定只有一个字符串后会存储在常量区 NSString *name2 = @"haha"; //确定只有一个字符串后会存储在常量区 NSString *name3 = [[NSString alloc]initWithFormat:@"%@ %@ %@",@"aa",@"bb",@"cc"];//此时字符串个数不确定,然后会存储在堆区 //不是所有的对象都能使用copy,只有遵守了NSCopying协议的对象才能使用copy |
黄金原则 | // MRC管理内存一条原则:有加1就要有减1,有谁开辟就有谁来释放,谁加1谁就减1 assign :基本数据类型使用 retain :所有对象类型都能使用 copy:遵守了copy协议并且实现了协议的才能用,慎重使用,能把字符串从栈区copy到堆区 代理使用assign,block使用copy,对于NSString一般使用Copy |
类的内存分配长度
语法糖也是一种便利构造器 | NSLog(@"%lu",sizeof([Personclass])); //类的长度为8,与C语言中的指针相似 NSLog(@"%lu",sizeof(p1)); //类的长度为8,与C语言中的指针相似 [p1 release]; // NSLog(@" test2.name =%@",p1.name);//标记性删除,不一定会崩溃 // OC的容器类会对里面的对象执行retain操作,在数组里面person对象的计数量加1,当对象被移除的时候会执行减1操作 NSArray *array = [NSArray arrayWithObjects:person1,person2, nil];//凡是便利构造器不需要release, |
深拷贝与浅拷贝 的区别与用法 | NSString *name1 = [[NSStringalloc]initWithFormat:@"%@",@"xxx"];//NSString 使用copy时是浅拷贝 NSString *name2 = [name1copy]; //这种拷贝没有重新分配空间,是一种浅拷贝,等价于retain,只拷贝指针,深拷贝拷贝的内容 NSString *name3 = [name1mutableCopy]; //此时mutableCopy为深拷贝 // NSMutable类型使用copy或者mutableCopy都是深拷贝 NSMutableString *result2 = [mutablestring copy]; //copy 出来的东西都是不可变的,所以不能使用拼接,但此时为深拷贝 NSMutableArray *array5 = [NSMutableArrayarrayWithObjects:@"name1",@"name2",nil]; NSMutableArray *array6 = [array5copy]; //此处为深拷贝 NSMutableArray *array7 = [array5mutableCopy]; //此处为深拷贝 |
@autoreleasepool | @autoreleasepool { //一级 pool @autoreleasepool { //二级 pool [test2 retain]; @autoreleasepool { //三级 pool [test2 release]; } [test2 retain]; } } //出了最近的自动释放池后autorelease就会执行减1操作(因为autoreleasepool内可以套无数个autoreleasepool)) NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];//。。内容。。 [pool release]; 这两句相当于 @autoreleasepool { 内容 。。。。} |
dealloc | - (void)dealloc { [_name release]; //对成员变量进行最后的释放 [super dealloc]; //必有,而且需要放在最下面 } |
getter方法 | - (NSString*)name { return[[_name retain]autorelease]; //适用于retain与copy的方法,如果是assign方法,直接返回就行 } |
setter方法 | - (void)setName:(NSString *)name { if(_name != name) { [_name release]; _name = [name copy]; //copy 方法此处使用copy,retain方法此处用retain,assign方法直接赋值就可 } } |
初始化方法 | - (id)initWithName:(NSString*)name withSex:(NSString*)sex withAge:(NSInteger)age { self = [superinit]; if(self) { /**** 为了避免内存过度释放,选用self.成员变量,会自动retain/copy +1 *****/ //第一种 _name = name; _sex = sex; _age = age; //第二种 self.name = name; self.sex = sex; self.age = age; /*** 但是,在子类再次进行初始化的时候会出现父类执行子类的set方法的情况,因此出现下面的写法 ****/ //第三种 _name = [namecopy]; _sex = [sexcopy]; _age = age; } returnself; } |
@property 成员变量成名
三大属性: retain、assign、copy
| @property (nonatomic,copy)NSString *name; //NSString一般使用copy方法 @property (nonatomic,copy)NSString *sex; @property (nonatomic,assign)NSInteger age; //等价于实现了:成员变量声明,setter方法 getter方法 设置成员变量的@property属性时,默认为atomic,提供多线程安全。在多线程环境下,原子操作是必要的,否则有可能引起错误的结果。Nonatomic : 禁止多线程,变量保护,提高性能。读写属性方面默认可读可写(readwrite),使用只读属性时需要声明(readonly) Assign:对基础数据类型(NSInteger,CGFloat)和C数据类型(int, float, double, char)等等 Retain:对其他NSObject和其子类对参数进行release旧值,再retain新值 Copy:对NSString 它指出,在赋值时使用传入值的一份拷贝。拷贝工作由copy方法执行,此属性只对那些实行了NSCopying协议的对象类型有效, retain 是指针拷贝,copy是内容拷贝 非ARC:(1)copy只用于NSString\block (2)retain适用于:除了NSString\block以外的OC对象 (3)assign:基本数据类型、枚举、结构体(非OC对象),当2个对象相互引用,一端retain,一端用assign ARC:(1)copy只适用于NSString\block (2)strong适用于:除了NSString\block以外的OC对象(3)weak:,当2个对象相互引用,一端strong,一端用weak(4)assign:基本数据类型、枚举、结构体(非OC对象)
|
| OcLesson11_NSDate |
NSDate | //如果NSDate只能打印出地0时区的时间,获取当前的时间在实际上开发中很少使用 NSDate *date = [NSDatedate]; //即使时间 NSLog(@"%@",date); NSDate *date1 = [NSDatedateWithTimeIntervalSince1970:1435235000];//默认时间单位为秒 NSLog(@"date1 = %@",date1); |
NSTimeInterval | NSTimeInterval time = [date1 timeIntervalSinceDate:date];//计算两个日期的间隔时间,前➖后 NSLog(@"%f",time); NSDate *date2 = [NSDatedateWithTimeIntervalSinceNow:70]; NSTimeInterval time2 = [date2timeIntervalSinceDate:date]; if (time2 >0 && time2 < 60) { NSLog(@"发生在%f s前",time2); } else if(time2 >60 && time2 <3600){ NSLog(@"发生在%.0f分钟前",time2/60); }else{ NSLog(@"发生在%.0f小时前",time2/3600); }
|
日期和字符串相互转化的辅助类 | //日期和字符串相互转化的辅助类 NSDateFormatter *formatter = [[NSDateFormatteralloc]init]; [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss aa"]; //先使用系统提供好的系统格式 // NSDateFormatterShortStyle NSDateFormatterLongStyle // [formatter setTimeStyle:NSDateFormatterFullStyle]; // [formatter setDateStyle:NSDateFormatterFullStyle]; NSString *dateString = [formatterstringFromDate:date]; //辅助类 NSLog(@"dateString = %@",dateString); //把字符串转换为时间 NSDate *finalDate = [formatterdateFromString:@"2014-06-25 14:49:17"]; NSLog(@"finalDate = %@",finalDate); |
获取当前的Locale的详细时间 | //获取当前的Locale的详细时间 NSLocale *cn = [NSLocalecurrentLocale]; NSLog(@"cn = %@",[datedescriptionWithLocale:cn]); NSDate *earlier = [date1earlierDate:date2]; NSDate *later = [date1laterDate:date2];
|