协议: protocol
遵守了协议的类,这个类就拥有了这份协议中的所有的方法的声明,而不用自己去定义.
@protocol 协议名称 <NSObject> //这里写方法的声明; @end
- 协议中不能写属性.
- 可以写方法的声明
也可以写(开发中不会写)@property,但是协议中的@property只会生成get set的声明,没有实现.
如果一个类想要拥有某个协议中的所有的方法的声明,就只要遵守这个协议就可以了.
//遵守协议的格式 @interface 类名 : 父类名 <协议名称> // : 冒号 是继承 <>尖括号是遵守协议 @end
类遵守协议的效果:就是拥有协议的声明 ,不会自动实现.如果没有实现协议中的方法,编译的时候会给一个警告,执行的时候如果调用了没实现的方法,就会报错.如果父类遵守协议,相当于子类也继承了.
@interface 类名 : 父类名 <协议名1,协议名2,......>
@end
//如果一个类遵守了多分协议,这个类就拥有了所有协议中的方法和声明
@required
与 @optional
@required
修饰的方法,如果遵守这个协议的类不去实现的话,编译器就会报警告@optional
修饰的方法,如果遵守这个协议的类不去实现的话,编译器不会报警告@required
是必须遵守实现的,@optional
可以不实现.@required
.@protocol HMSportPotocol<NSObject>
@protocol HMStudyProtocol<HMStudyPorocol,HMPlayPotocol>
@interface HMPerson : NSObject <HMStudyPotocol>//继承study协议同时自动继承了它的父协议Sport,Play协议.
Foundation框架中有个协议也叫NSObject.协议名字和类名一样不冲突
NSObject类遵守了NSObject协议.
所以NSObject类里面拥有了NSObject协议中的所有声明.
所以所有的OC类都拥有了NSObject协议中的方法声明
协议的规范:要求##所有的协议##直接或者间接的##从NSObject基协议继承##.
分类: 将一个类分为多个模块,为一个类添加方法
延展: 专门用来私有化类的成员的
协议: 定义一份协议,可以让其他的类来遵守这个协议,遵守后获得协议中所有方法声明
继承: 子类继承父类,子类就拥有了父类的所有的成员
//NSObject指针或者id指针都可以.回一下有啥区别?
id<协议名> 指针名;
id id1;
//这样,id1指针要求指向的对象必须遵守HMSportProtocol协议,否则就给黄色警告.
id id1;
HMPerson
人类:
女朋友类:
美国女孩.
印度女孩.
火星女孩.
狗...
只要会洗衣服,会做饭,就可以
@protocol HMGFProtocol <NSObject>
- (void)xiYiFu;
- (void)cook;
@optional
- (void)haveAGoodJob;
- @end
@interface HMPerson : NSObject
@property(nonatomic,strong)NSString *name;
@property(nonatomic,assign)int money;
//重点是下面的,人类拥有一个女朋友对象,谁都行,只要遵守GF协议这个也就是代理对象.帮助当前对象来完成某件事情
//下面的实际实在
@property(nonatomic,strong)id girlFriend;//@implementation中的.
- (void)talkLove;
{
NSLog(@"哈尼,我回来了~");
[_girlFriend xiYiFu];
[_girlFriend cook];
NSLog(@"亲爱的你真好,明天继续哦~");
}
@end
int main()
{
HMPerson *p1 = [HMPerson new];
p1.name = @"李凯";
p1.money = INT32_MAX;
HMGirl *fj = [HMGirl new];
p1.girlFriend = fj;//如果没有遵守协议这句话就黄了,报警高
[p1 talkLove];//如果没有实现方法,就会谈崩了.
return 0;
}
提供一个方法打印表格.
苹果或者牛X的第三方事先将程序员在编程的时候经常要用到的一些功能写好.把这些功能封装在一个一个的类中,这些类的集合就叫做框架.
-不同的框架中的类是用来做不同的事情的
- Foundation: 包.有很多类 函数 数据类型.
- 基础,基本,这个框架中定义的是我们最基础的类
- 其他的框架都是基于Foundation框架的
- AVFoundation : 音频视频相关的
- UIKit: 做界面的
- CoreLocation : 定位有关的
NSString
NSURL
NSMutableString
NSArray
NSMutableArray
NSNumber
NSDictionary
NSMutableDictionary
NSFileManager
NSData
NSDate
CGPoint
CGSize
CGRect
NSValue
copy
单例
标准的创建方式
NSString *str1 = [[NSString alloc] init];
.
这样的方式创建的字符串对象中存储的数据是@""
,空字符串.
所以为了快速的创建NSString对象
OC提供了一种更为快捷的方式创建NSString对象.
使用@符号
@”jack” 是创建NSString对象的简写方式
本质上是一个NSString对象,对象存储的是”jcak”这个字符串
str中存储的是对象的地址.NSString *str = @"jack";
.
实际上是创建了一个字符串对象,将jack存储进去.
%p 是打印地址
%@ 是打印指针指向的对象.调用对象description方法.
那么这个字符串对象是存储在常量区中的.
如果调用类方法来创建字符串对象,这个对象是存储在堆空间中的
NSString *str1 = @”jack”; //这个字符串对象存储在常量区的(数据段)
NSString *str2 = [NSString new]; //这个字符串对象是存储在堆区的.
NSLog(@”str1 = %p”,str1);
NSLog(@”str2 = %p”,str2);
你会发现,这两个对象的地址相差很多 说明他们不在1个区中.
存储在内存中的字符串对象,无论是在堆区还是常量区
这个字符串对象的内容是无法更改的.字符串一旦创建,这个字符串对象中存储的字符串数据就不能改变
永远都只能存储这个为NSString指针重新赋值一个字符串的时候,并不是修改原来的哪个字符串
而是重新的创建了一个字符串对象,将这个新的字符串对象的地址赋值给指针==不可更改性,即针对堆区,也针对常量区字符串对象==
比如:当准备要在常量区创建字符串对象的时候,会先检查常量区中是否有内容相同的字符串对象,如果有,直接指向,没有才会创建.
堆区:
1. 如果字符串创建在堆区,不回去检查常量区.
2. 只会检查堆区中是否有相同内容的字符串对象,如果有直接指向,如果没有才会重新创建
存储爱常量区中的字符串不会被回收.
NSString *str1 = @"jcak"; str1 = nil;
.为什么不回收.因为对象的引用计数器不为0;
为什么字符串不允许回收呢?
为了提高效率.不止苹果,所有的语言都认为字符串你用了一次肯定还会用第二次
提高效率, 当第二次使用的时候,效率就高了.因为不用创建字符串对象了.
@property (readonly) NSUInteger length;
- (unichar)characterAtIndex:(NSUInteger)index;
返回值是unichar,打印用大C %C .+ (instancetype)stringWithFormat:(NSString *)format, ...
, ...
代表随便给多少个参数- (BOOL)isEqualToString:(NSString *)aString;
;== 判断的是左右两边的值是否相等.
NSString *str1 = @"jack"; NSString *str2 = [NSString stringWithFormat:@"jack"];
这个str1 和 str2的值就不一样了,在不同的区
所以判断两个字符串的内容是否相等千万不要用 ==
而是用对象方法.
+ (nullable instancetype)stringWithUTF8String:(const char *)nullTerminatedCString;
nullable
代表返回的对象可能是nil.当转换失败的时候.
[str UTF8String];
不太常用 @property (nullable, readonly) __strong const char *UTF8String
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError **)error;
path : 路径
encoding: 字符编码 建议NSUTF8StringEncoding
NSString *str = @"我爱你!";
NSError *err = nil;
BOOL res = [str writeToFile:@"/Users/admin/Desktop/abc.txt" atomically: NO encoding:NSUTF8StringEncoding error:&err];
// YES 创建临时文件,成功在拷贝到指定目录.NO 效率高,不安全. 要效率,建议NO
//二级指针,error:如果发生错误err就会指向一个错误对象,可以得到错误的信息.
+ (nullable instancetype)stringWithContentsOfFile:(NSString *)path encoding:(NSStringEncoding)enc error:(NSError **)error;
str的值如果是nil 说明失败.
err的值如果不是nil 说明失败
可以读取一个网页的源代码.ftp服务器上的文件也可以读取.
URL:同意资源路径,也就是一个网址ftp文件的地址.磁盘上的文件的地址.
网址的URL标准写法: http://www.itheima.com
ftp文件的URL标准写法: ftp://server.itheima.com/aa.avi
磁盘文件路径: file:///Users/Itcast/Desktop/abc.txt
NSString可以从一个URL路径中读写数据.
NSURL *url1 = [NSURL URLWithString:@"http://www.itheima.com"];
NSURL *url2 = [NSURL URLWithString:@"ftp://server.itheima.com/1.txt"];
NSURL *url3 = [NSURL URLWithString:@"file:///Users/Itcast/Desktop/abc.txt"];
+ (nullable instancetype)stringWithContentsOfURL:(NSURL *)url encoding:(NSStringEncoding)enc error:(NSError **)error;
往NSURL中写入数据
- (BOOL)writeToURL:(NSURL *)url atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)enc error:(NSError **)error;
- (NSComparisonResult)compare:(NSString *)string;
返回值是枚举-1 0 1指定选项的比较
int len = [str1 compare:str2 options:NSCaseInsensitiveSearch];
;int len = [str1 compare:str2 options: NSLiteralSearch];
int len = [str1 compare:str2 options: NSNumericSearch];
- (BOOL)hasPrefix:(NSString *)str;
- (BOOL)hasSuffix:(NSString *)str;
@"i love rose";
@"love";
范围: 起始下标是:2 长度: 4
- (NSRange)rangeOfString:(NSString *)searchString
返回值代表子字符串在主串中的范围.
返回值是个NSRange 这是1个结构体.
typedef struct _NSRange {
NSUInteger location;
NSUInteger length;
} NSRange;
location: 代表这段范围的起始下标.
length: 代表匹配的长度.
如果在主串中没有找到子串. 返回的NSRange结构体变两的length的值就是0.location的值就是NSUInteger的最大值.
所以,如果我们要判断是否在主串中找了子串.
1). 判断返回的NSRange结构体的length是否为0
2). 也可以判断location的值是否为最大值.NSNotFound就代表它的最大值.
如果找到的情况下:
location的值 是第一次匹配到的下标.
length的值就是子串的长度.