OC基础--协议和字符串

协议

什么是协议

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

main函数中

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;
}

代理设计模式的规范

  1. 一般情况下, 当前协议属于谁, 我们就将协议定义到谁的头文件中协议的名称一般以它属于的那个类的类名开头, 后面跟上protocol或者delegate协议中的方法名称一般以协议的名称protocol之前的作为开头一般情况下协议中的方法会将触发该协议的对象传递出去一般情况下一个类中的代理属于的名称叫做 delegate当某一个类要成为另外一个类的代理的时候, 一般情况下在.h中用@protocol 协议名称;告诉当前类 这是一个协议. 在.m中用#import真正的导入一个协议的声明

字符串

什么是NSString

一个NSString对象就代表一个字符串(文字内容) 一般称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);

字符串读写(通过URL方式)

URL简介

1.URL的全称是Uniform Resource Locator(统一资源定位符)
2.URL是互联网上标准资源的地址
3.互联网上的每个资源都有一个唯一的URL,它包含的信息指出资源的位置
4.根据一个URL就能找到唯一的一个资源

URL书写格式

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]);
    }

注意点:

  • 创建的URL两个方法的区别:
  • URLWithString:

    • 优点:能获取本地数据,也可以获取网路数据
    • 缺点:方法不支持中文路径,所以要想成功创建URL,必须先对路径字符串进行编码
  • fileURLWithPath:

    • 优点:方法支持中文,并且省略file://协议头,
    • 缺点:只能获取本地数据,不能获取网路数据

如何获取网络路径信息

通过 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协议头

writeToFile: 和writeToURL: 方法的区别?

1.writeToFile:用于将数据写入本地路径中的文件中

NSString *path2 = @"/Users/king/Desktop/abc.txt";
BOOL flag = [str writeToFile:path2 atomically:YES encoding:NSUTF8StringEncoding error:nil];

2.writeToURL:既可以将数据写入到本地路径的文件中,也可以将数据写入网络路径的文件中

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(@"不是动态图片");
}

如何判断字符串中是否包含 sjl ?本质是什么?

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);

如何C语言字符串和OC字符串之间的转换?

char *cStr = "usb";
NSString *str = [NSString stringWithUTF8String:cStr];
NSLog(@"str = %@", str);
NSString *newStr = @"sjl";
const char *cStr2 = [newStr UTF8String];
NSLog(@"cStr2 = %s", cStr2);

 

 

NSMutalbleString基本概念

NSMutableString和NSString的区别?

1.NSString是不可变的, 里面的文字内容是不能进行修改的

2.NSMutableString是可变的, 里面的文字内容可以随时更改

3.NSMutableString能使用NSString的所有方法

什么是可变字符串?什么是不可变字符串?

1.不可变字符串:指的是字符串在内存中占用的存储空间固定,并且存储的内容不能发生变化

2.可变字符串:指的是字符串在内存中占用的存储空间可以不固定,并且存储的内容可以被修改

NSMutalbleString常用方法

对可变字符串增删改查

NSMutableString *strM = [NSMutableString stringWithFormat:@"www.520it.com.520"];

在字符串后面添加一段字符串?

[strM appendString:@"/image"];
[strM appendFormat:@"/age is %i", 10];
NSLog(@"strM = %@", strM);

如何删除字符串中的520?

先利用rangeOfString和deleteCharactersInRange方法配合起来删除指定的字符串

先查找出520在字符串中的位置

NSRange range = [strM rangeOfString:@"520"];

再删除520

[strM deleteCharactersInRange:range];
NSLog(@"strM = %@", strM);

如何在520前面插入love这个单词?

// insertString : 需要插入的字符串
// atIndex: 从哪里开始插入
NSRange range = [strM rangeOfString:@"520"];
[strM insertString:@"love" atIndex:range.location];
NSLog(@"strM = %@", strM);

如何将字符串中的520替换为530?

// 如果是调用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);

方法三:

// 创建一个空得字符串
NSMutableString *strM  = [NSMutableString string];
for (int i = 0; i < 3; ++i) {
    // 1.添加一个520it
    [strM appendString:subStr];
    // 2.添加一个空格
    [strM appendString:@" "];
}
[strM deleteCharactersInRange:NSMakeRange(strM.length - 1, 1)];
NSLog(@"strM = |%@|", strM);
 
 

你可能感兴趣的:(OC基础--协议和字符串)