1.其他语言有接口的概念,接口就是一堆方法的声明没有实现.
2.OC中没有接口的概念,OC中的接口就是协议.
3.协议Protocol是由一系列的方法声明组成的
@protocol 协议名称 <NSObject> // 方法声明列表 @end
@interface 类名 : 父类 <协议名称1, 协议名称2,…> @end
注意:
1.一个类可以遵守一个或多个协议
2.任何类只要遵守了Protocol,就相当于拥有了Protocol的所有方法声明
1.继承之后默认就有实现, 而protocol只有声明没有实现
2.相同类型的类可以使用继承, 但是不同类型的类只能使用protocol
3.protocol可以用于存储方法的声明, 可以将多个类中共同的方法抽取出来, 以后让这些类遵守协议即可
基协议:是基协议,是最根本最基本的协议,其中声明了很多最基本的方法。建议每个新的协议都要遵守NSObject协议
1.协议只能声明方法, 不能声明属性
2.父类遵守了某个协议, 那么子类也会自动遵守这个协议
3.在OC中一个类可以遵守1个或多个协议 注意: OC中的类只能有一个父类, 也就是说OC只有单继承
4.OC中的协议又可以遵守其它协议, 只要一个协议遵守了其它协议, 那么这个协议中就会自动包含其它协议的声明
1.注意: 如果没有使用任何关键字修饰协议中的方法, 那么该方法默认就是required的
2.注意: @required和@optional仅仅使用程序员之间交流, 并不能严格的控制某一个遵守该协议的类必须要实现该方法, 因为即便不是实现也不会报错, 只会报一个警告
3.@required 如果协议中的方法是@required的, 要求遵守协议的类实现@required所修饰的方法,如果没有实现该方法, 那么会报一个警告
4.@optional 如果协议中的方法是@optional的, 遵守协议的类可选择实现@optional所修饰的方法,如果没有实现该方法, 那么不会报警告
类型限定就是限定一个类必须遵守某个协议
格式:数据类型<协议名称> 变量名
@property (nonatomic, strong) Wife<WifeCondition> *wife;
1.类型限定是写在数据类型的右边的
2.虽然在接受某一个对象的时候, 对这个对象进行了类型限定(限定它必须实现某个协议), 但是并不意味着这个对象就真正的实现了该方法. 所以每次在调用对象的协议方法时应该进行一次验证
if ([self.wife respondsToSelector:@selector(cooking)]) { [self.wife cooking]; }
应用场景:
1.当A对象想监听B对象的一些变化时, 可以使用代理设计模式 保姆想监听婴儿的变化, 那么保姆就可以成为婴儿的代理, 当婴儿发生变化之后保姆就可以监听到
2.当B对象发生一些事情, 想通知A对象的时候, 可以使用代理设计模式 婴儿想通知保姆, 那么就可以 让保姆成为婴儿的代理, 只要保姆成为婴儿的代理, 以后婴儿发生变化就可以通知保姆
3.当对象A无法处理某些行为的时候,想让对象B帮忙处理(让对象B成为对象A的代理对象) 婴儿无法自己吃东西, 也无法自己入睡, 所以可以让保姆帮忙处理. 只要让保姆成为婴儿的代理就可以帮婴儿喂它吃东西和哄他睡觉
用什么类型来接受遵守协议的对象?
用id类型来接受
// 如果使用id类型来接收保姆, 如果将来换保姆了, 婴儿类不用修改代码 @property (nonatomic, strong) id<BabyProtocol> nanny;
1.声明婴儿是一个类(将当前对象传出去) @class Baby;
2.定义代理协议,协议中声明代理要帮婴儿做的事 (只声明方法,将婴儿传给代理,让代理实现协议中方法,注意协议格式)
@protocol BabyDelegate <NSObject> //喂婴儿吃饭 - (void)babyEat:(Baby *)baby; //哄婴儿睡觉 - (void)babySleep:(Baby *)baby; @end
3.将代理作为属性,类型限定代理遵守协议
@property (nonatomic, weak) id <BabyDelegate> delegate;
4.声明方法,方法里调用代理,调用代理实现的协议方法,让代理帮婴儿吃饭,睡觉
//婴儿饿了要吃饭 - (void)hurgry; //婴儿醒了要睡觉 - (void)wake;
5.实现调用代理者的方法
@implementation Baby - (void)hurgry{ // 6.判断代理是否实现了协议中的方法 //7.如果代理实现了协议中的方法,就调用 if ([self.delegate respondsToSelector:@selector(eat:)]) [self.delegate eat:self]; } - (void)wake{ if ([self.delegate respondsToSelector:@selector(sleep:)]) [self.delegate sleep:self]; } @end
6.导入协议
@protocol BabyDelegate;
7.遵守协议
@interface Nurse : NSObject <BabyDelegate> @end
8.实现协议中的方法,(喂婴儿,让婴儿吃饭,拿到婴儿才能给婴儿做事)
@implementation Nurse - (void)eat:(Baby *)baby{ baby.hurgryValue += 10; NSLog(@"喂婴儿吃饭!饥饿值:%lu", baby.hurgryValue); } - (void)sleep:(Baby *)baby{ baby.sleepValue += 5; NSLog(@"摇婴儿睡觉!疲劳值:%lu", baby.sleepValue); } @end
int main(int argc, const char * argv[]) { @autoreleasepool { //11.创建所需对象 Baby *b = [[Baby alloc]init]; Nurse *n = [[Nurse alloc]init]; //12.将代理对象作为接受代理者的代理 //(让保姆作为婴儿的代理) b.delegate = n; //设定婴儿初始饥饿值,疲劳值 b.hurgryValue = -5; b.sleepValue = -5; //13.接受代理者调用代理者的方法 //(婴儿饿了,醒了,需要吃饭和哄一哄) [b hurgry]; [b wake]; } return 0; }
一个NSString对象就代表一个字符串(文字内容) 一般称NSString为字符串类
1.通过 @"" 直接创建
// 如果通过@""创建字符串, 那么会将字符串放到常量区中 // 如果是字符串常量, 那么只要内容相同 , 不会重复创建 NSString *str1 = @"sjl";
2.通过 alloc 或者类工厂方法
// 如果是通过alloc或者类工厂方法创建, 那么会将字符串放到堆区中 NSString *str2 = [[NSString alloc] initWithString:@"sjl"]; NSString *str3 = [NSString stringWithFormat:@"king"];
/* file: 文件路径, encoding: 编码英文 iOS-5988-1 中文 GBK GBK2312 , 一般情况填写UTF-8 error: 如果读取错误, 会将错误信息保存到error中 ,如果读取正确, 就没有error = nil 注意: 以后在OC方法中但凡看到XXXofFile的方法, 传递的一定是全路径(绝对路径) */ NSString *path = @"/Users/king/a.txt"; NSError *error = nil; // 从文件中读取字符串 NSString *str = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; if (error == nil) { NSLog(@"str = %@", str); }else { //localizedDescription 打印真正错误信息 NSLog(@"error = %@", [error localizedDescription]); }
NSString *str = @"iOS1010基础班"; // atomically 如果传入YES, 字符串写入文件的过程中如果没有写完, 那么不会生成文件 // 如果传入NO, 字符串写入文件的过程中如果没有写完, 会生成文件 NSString *path2 = @"/Users/king/abc.txt"; BOOL flag = [str writeToFile:path2 atomically:YES encoding:NSUTF8StringEncoding error:nil]; NSLog(@"flag = %i", flag);
1.URL的全称是Uniform Resource Locator(统一资源定位符)
2.URL是互联网上标准资源的地址
3.互联网上的每个资源都有一个唯一的URL,它包含的信息指出资源的位置
4.根据一个URL就能找到唯一的一个资源
URL = 协议头://主机地址/路径
1.通过alloc或者类工厂方法
NSURL *url = [NSURL URLWithString:@"file:///Users/king/Desktop/str.txt"]; NSURL *url = [[NSURL alloc] initWithString:@"file:///Users/king/Desktop/str.txt"];
2.通过文件路径创建( fileURLWithPath: 默认就是file: 协议 所有不用再写协议头)
NSURL *url = [NSURL fileURLWithPath:@"/Users/king/Desktop/str.txt"];
1.获取本地路径信息
方法一
// 字符串保存路径 NSString *path = @"file://192.168.31.210/Users/king/Desktop/abc.txt"; NSLog(@"url编码前: %@", path); // 将路径中中文转换为UTF-8编码格式 path = [path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSLog(@"url编码后: %@", path);
方法二
// 字符串保存路径,如果访问本机的文件, 可以省略主机地址 NSString *path = @"file:///Users/king/abc.txt"; NSLog(@"url编码前: %@", path); // 将路径中中文转换为UTF-8编码格式 path = [path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSLog(@"url编码后: %@", path); NSURL *url = [NSURL URLWithString:path];
NSURL *url = [NSURL fileURLWithPath:@"/Users/king/abc/str.txt"]; NSError *error = nil; NSString *str = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error]; if (error == nil) { NSLog(@"str = %@", str); }else{ NSLog(@"error = %@", [error localizedDescription]); }
URLWithString:
fileURLWithPath:
通过 URLWithString
NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"]; NSString *str = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil]; NSLog(@"str = %@", str);
NSString *str = @"你大爷"; NSString *path = @"file:///Users/king/Desktop/未命名文件夹/abc.txt"; path = [path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSURL *url = [NSURL URLWithString:path]; [str writeToURL:url atomically:YES encoding:NSUTF8StringEncoding error:nil];
NSString *str = @"你二大爷"; NSString *path = @"/Users/king/Desktop/未命名文件夹/abc.txt"; NSURL *url = [NSURL fileURLWithPath:path]; [str writeToURL:url atomically:YES encoding:NSUTF8StringEncoding error:nil];
1.如果多次往同一个文件中写入内容,那么后一次的会覆盖前一次的
2.方法名中没有file,路径中要添加上file协议头,如果方法名中有file,路径中就不需要file协议头
NSString *path2 = @"/Users/king/Desktop/abc.txt"; BOOL flag = [str writeToFile:path2 atomically:YES encoding:NSUTF8StringEncoding error:nil];
NSString *str = @"USB"; NSString *path = @"/Users/king/Desktop/未命名文件夹/abc.txt"; NSURL *url = [NSURL fileURLWithPath:path]; [str writeToURL:url atomically:YES encoding:NSUTF8StringEncoding error:nil];
NSString *str1 = @"abc"; NSString *str2 = @"ABC";
BOOL flag = [str1 isEqualToString:str2]; NSLog(@"flag = %i", flag);
flag = (str1 == str2); NSLog(@"flag = %i", flag);
使用方法compare:
// NSOrderedAscending 前面的小于后面的 // NSOrderedSame, 两个字符串相等 // NSOrderedDescending 前面的大于后面的 switch ([str1 compare:str2]) { case NSOrderedAscending: NSLog(@"str1小于str2"); break; case NSOrderedSame: NSLog(@"str1等于str2"); break; case NSOrderedDescending: NSLog(@"str1大于str2"); break; }
switch ([str1 caseInsensitiveCompare:str2]) { case NSOrderedAscending: NSLog(@"str1小于str2"); break; case NSOrderedSame: NSLog(@"str1等于str2"); break; case NSOrderedDescending: NSLog(@"str1大于str2"); break; default: break; }
// 定义一个字符串 NSString *str = @"http://www.king129.com/img/logo.gif";
// 本质就是从字符串的第一个字符开始匹配, 只要不匹配就返回NO if ([str hasPrefix:@"http://"]) { NSLog(@"是一个URL"); }else { NSLog(@"不是一个URL"); }
// 本质就是从字符串的最后一个字符开始匹配, 只要不匹配就返回NO if ([str hasSuffix:@".gif"]) { NSLog(@"动态图片"); }else{ NSLog(@"不是动态图片"); }
NSString *str = @"abcd"; // 只要str中包含该字符串, 那么就会返回该字符串在str中的起始位置以及该字符串的长度 // location从0开始 , length从1开始 // 如果str中没有需要查找的字符串, 那么返回的range的length=0, location = NSNotFound NSRange range = [str rangeOfString:@"sjl"]; // if (range.location == NSNotFound) { if (range.length == 0){ NSLog(@"str中没有需要查找的字符串"); }else{ NSLog(@"str中有需要查找的字符串"); NSLog(@"location = %lu, length = %lu", range.location, range.length); }
NSString *str = @"<head>king</head>";
1.动态计算截取的起始位置
NSUInteger location = [str rangeOfString:@">"].location + 1;
2.动态计算截取的长度
// 注意:rangeOfString是从左至右的开始查找, 只要找到就不找了 NSUInteger length = [str rangeOfString:@"</"].location - location; NSRange range = NSMakeRange(location, length); NSString *newStr = [str substringWithRange:range]; NSLog(@"str = %@", str); NSLog(@"newStr = %@", newStr);
/* <head>小码哥</head> --> 小码哥</head> --> 小码哥 <head>小码哥</head> --> <head>小码哥 --> 小码哥 */ NSUInteger location = [str rangeOfString:@">"].location + 1; NSString *newStr = [str substringFromIndex:location]; NSLog(@"newStr = %@", newStr); location = [newStr rangeOfString:@"</"].location; // 改变了指针的指向, 并不是修改了原来的字符串 newStr = [newStr substringToIndex:location]; NSLog(@"newStr = %@", newStr);
//需求: 将&符号替换为/ NSString *str = @"http:&&www.520it.net.cn&img&logo.gif"; // OccurrencesOfString: 要替换谁 // withString: 用谁替换 NSString *newStr = [str stringByReplacingOccurrencesOfString:@"&" withString:@"/"]; NSLog(@"newStr = %@", newStr);
NSString *str = @"HTTP://www.520it.com/img/iOS.GIF"; NSCharacterSet *set = [NSCharacterSet uppercaseLetterCharacterSet]; NSString *newStr = [str stringByTrimmingCharactersInSet:set]; NSLog(@"newStr = |%@|", newStr);
// 本质就是判断是否以 / 开头 if([str isAbsolutePath]) { NSLog(@"是绝对路径"); }else{ NSLog(@"不是绝对路径"); }
// 本质就是获取最后一个 / 后面的内容 NSString *newStr = [str lastPathComponent]; NSLog(@"%@", newStr);
// 本质就是删除最后一个 / 后面的内容包括 / 也会被删除 NSString *newStr = [str stringByDeletingLastPathComponent]; NSLog(@"%@", newStr);
/* 本质:就是在字符串的末尾加上一个/ 和指定的内容 注意: 如果路径后面已经有了/, 那么就不会添加了 如果路径后面有多个/, 那么会自动删除多余的/, 只保留一个 */ NSString *newStr = [str stringByAppendingPathComponent:@"king"]; NSLog(@"%@", newStr);
// 本质就是从末尾开始查找,截取第一个 .(点)后面的内容 NSString *newStr = [str pathExtension]; NSLog(@"%@", newStr);
// 本质就是从末未开始查找,删除第一个 点后点后面的内容 NSString *newStr = [str stringByDeletingPathExtension]; NSLog(@"%@", newStr);
// 本质就是在末尾添加 一个 点后指定的内容 NSString *newStr = [str stringByAppendingPathExtension:@"jpg"]; NSLog(@"%@", newStr);
NSString *str = @"abc";
NSString *newStr = [str uppercaseString]; NSLog(@"%@", newStr);
NSString *newStr2 = [newStr lowercaseString]; NSLog(@"%@", newStr2);
NSString *newStr = [str capitalizedString]; NSLog(@"%@", newStr);
NSString *str1 = @"110"; NSString *str2 = @"120"; // str1 + str2; // 错误 int value1 = [str1 intValue]; int value2 = [str2 intValue]; NSLog(@"sum = %i", value1 + value2); // 注意: 如果不是int,double,float,bool,integer,longlong这些类型就不要乱用 NSString *str3 = @"abc"; int value3 = [str3 intValue]; NSLog(@"value3 = %i", value3);
char *cStr = "usb"; NSString *str = [NSString stringWithUTF8String:cStr]; NSLog(@"str = %@", str); NSString *newStr = @"sjl"; const char *cStr2 = [newStr UTF8String]; NSLog(@"cStr2 = %s", cStr2);
1.NSString是不可变的, 里面的文字内容是不能进行修改的
2.NSMutableString是可变的, 里面的文字内容可以随时更改
3.NSMutableString能使用NSString的所有方法
1.不可变字符串:指的是字符串在内存中占用的存储空间固定,并且存储的内容不能发生变化
2.可变字符串:指的是字符串在内存中占用的存储空间可以不固定,并且存储的内容可以被修改
对可变字符串增删改查
NSMutableString *strM = [NSMutableString stringWithFormat:@"www.520it.com.520"];
[strM appendString:@"/image"]; [strM appendFormat:@"/age is %i", 10]; NSLog(@"strM = %@", strM);
先利用rangeOfString和deleteCharactersInRange方法配合起来删除指定的字符串
先查找出520在字符串中的位置
NSRange range = [strM rangeOfString:@"520"];
再删除520
[strM deleteCharactersInRange:range]; NSLog(@"strM = %@", strM);
// insertString : 需要插入的字符串 // atIndex: 从哪里开始插入 NSRange range = [strM rangeOfString:@"520"]; [strM insertString:@"love" atIndex:range.location]; NSLog(@"strM = %@", strM);
// 如果是调用NSString的字符串替换方法, 不会修改原有字符串, 而是生产一个新的字符串 NSString *newStr =[strM stringByReplacingOccurrencesOfString:@"520" withString:@"530"];
/* OccurrencesOfString: 需要替换的字符串 withString: 用什么替换 options: 替换时的搜索方式 range: 搜索的范围 返回值: 代表替换了多少个字符串 一般情况下OC方法要求传入一个参数如果没有*, 大部分都是枚举 一般情况下如果不想使用枚举的值, 可以传入0, 代表按照系统默认的方式处理 */ NSUInteger count = [strM replaceOccurrencesOfString:@"520" withString:@"530" options:0 range:NSMakeRange(0, strM.length)]; NSLog(@"strM = %@", strM); NSLog(@"count = %lu", count);
将3个520it拼接在一起, 中间用空格隔开 520it 520it 520it
NSString *subStr = @"520it";
方法一:
// 520it-
NSString *newStr = [subStr stringByAppendingString:@" "];
// 520it-520it
newStr = [newStr stringByAppendingString:subStr];
// 520it-520it-
newStr = [newStr stringByAppendingString:@" "];
// 520it-520-520it
newStr = [newStr stringByAppendingString:subStr];
方法二:
NSString *newStr = [subStr stringByAppendingString:@" "];; for (int i = 0; i < 2; ++i) { newStr = [newStr stringByAppendingString:subStr]; newStr = [newStr stringByAppendingString:@" "]; } // newStr = [newStr stringByReplacingCharactersInRange:NSMakeRange(newStr.length -1 , 1) withString:@""]; newStr = [newStr stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; NSLog(@"newStr = |%@|", newStr);
方法三: