1. try...catch...finally语句(异常处理)
- 作用(目的):保证程序就算出错也不崩溃先继续运行, 并且能在错误处获取错误信息
- 语句
1 @try{ 2 // 有可能出错的代码 3 } 4 @catch(NSException *ex){ 5 // 如果try中的代码出错, 那么就会跳转到catch代码块, 并且出错部分的地址会随之赋值给catch的参数, 也就是说, ex指向了异常部分的地址 6 // 异常处理代码都是写在这里 7 } 8 @finally{ 9 // finally是可选项, 可以添加也可以不添加, 如果添加了, 那么不管try代码块中的内容是否正确, finally中的代码一定会执行 10 }
- 优点: 可以使得程序在运行时就算是出现异常也不会崩溃, 并且如果程序在运行时出现了异常, 还能获取到异常部分的地址
- 缺点: 缺点也很明显, 不能处理C语言的异常, 一些底层错误, 也不会处理, 并且现在Xcode的调试功能越来越先进, 所以到现在用的不多
2. 类方法基础
1. 对象方法要调用就必须要先有个对象
2. 类方法不需要 [类名 类方法]
3. 对象方法 对象调用, 类方法, 类调用
4. 特点: 节约空间, 不需要创建对象; 提高效率, 调用的时候, 直接到代码区找到类, 找到类中的方法执行(对象方法, 先new对象, 通过指针找到对象, 找到对象里的isa指针, 通过isa指针找到类, 找到类中的方法)
5. 局限性: 在类方法中, 无法直接访问类的属性, 也无法通过self来调用当前类的对象方法
原因: 因为类方法的调用不需要创建对象的, 而属性只有对象创建了以后才有, 所有类方法在执行的时候, 这时候可能并没有创建对象, 也就无法访问属性了
同样, 在类方法执行的时候, 还没有对象, 而对象方法的调用必须要以来于对象来调用, 所以, 在类方法中不能直接使用 self 来调用当前类的其他对象方法
6. 类方法中虽然不能直接访问属性和类的其他对象方法, 但是可以在类方法中new一个对象, 通过这个对象来访问对象的属性和对象方法
+(LHPerson *)person{ // 同前篇, 假设已有LHPerson这个类 LHperson *p1 = [LHPerson new]; return p1; }
如果希望创建出来的对象的属性的值一开始就是指定好了的, 那么可以创建一个带参数(参数对应属性)的类方法,在方法里面创建对象,并且同时初始化对象的属性
1 +(LHPerson *)personWithName:(NSString *)name andAge:*(int)age{ 2 LHPerson *p1 = [LHPerson new]; 3 p1->_name = name; 4 p1->_age = age; 5 return p1; 6 }
7.重新回顾一下对象的创建这个操作
我们可以发现 [LHPerson new] 中, new其实就是一个类方法( LHPerson继承自NSObject 类, new是NSObject里的一个类方法), 这个方法的大致内容就是: 1. 创建一个对象; 2. 初始化这个对象; 它的返回值其实是返回的这个创建好的对象的地址(这也就是为什么在new对象的时候是用一个指针来接收了
8.如何写好一个类方法
我们写一个类, 就要为这个类提供一个和类名同名的类方法, 这个类方法来返回一个纯洁的对象
所谓纯洁的对象: 对象的属性的值都是默认值;
这个时候, 如果想要得到这个类的对象, 也可以直接调用这个同名的类方法来创建1个对象
假定有个类 LHPerson, 那么久需要有个类方法 person, 其作用其实跟new差不多即
LHPerson *p1 = [LHPerson new]; LHPerson *p2 = [LHPerson person];
这两条语句本质上是没有区别的, 都是new了一个对象, 并且这个对象的属性值都是默认值;
如果希望创建出来的对象的属性的值一开始就是指定好了的, 那么可以创建一个带参数(参数对应属性)的类方法,在方法里面创建对象,并且同时初始化对象的属性
1 +(LHPerson *)personWithName:(NSString *)name andAge:*(int)age{ 2 LHPerson *p1 = [LHPerson new]; 3 p1->_name = name; 4 p1->_age = age; 5 return p1; 6 }
NSString相关
- 本质上也是一个类, 是OC封装好的一个数据类型, 用来保存OC字符串的
- 按理来说, 完整的创建NSString 对象的方式应该是如下形式的
- NSString *str1 = [NSString new];
- NSString *str2 = [NSstring string];
- 但是由于NSString是OC中最常用的1个对象, 如果每次都这么创建就太麻烦了, 所以, 最后就封装成了 @“”的形式 @“jack”这就是1个NSString对象
- 注意: NSString *str1 = [NSString new]; 这种方式创建的字符串是一个空字符串 即 @“”, 而不是 nil !!!
- 既然NSString是1个类.那么就应该有很多很多的功能强大的方法.
1). 常用的类方法.
a. 将C语言的字符串转换为OC字符串对象.
+ (nullable instancetype)stringWithUTF8String:(const char *)nullTerminatedCString;
nullable: 代表返回的对象有可能是nil
b. 将变量拼接成1个新的OC字符串.
+ (instancetype)stringWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);
2). 常用的对象方法.
a. 得到字符串的长度.
- (NSUInteger)length;
NSUInteger 这货其实就是unsigned long
b. 得到指定下标的字符.
- (unichar)characterAtIndex:(NSUInteger)index;
在OC语言中 1个中文占据2个字节.
返回值是unichar 占据2个字节.
OC字符串中的字符 如果是英文字符占据1个字节 .如果是中文字符就占据2个字节.
打印unichar字符使用%C 这是大C
c. 判断两个字符串的内容是否相同.
如果要判断两个字符串的内容是否相同.不要使用==来判断.会出问题.
- (NSComparisonResult)compare:(NSString *)string;
返回的是1个枚举值.
NSOrderedAscending : 当前字符串比传入的字符串小.
NSOrderedSame: 一样
NSOrderedDescending 当前字符串比传入的字符串大
如果枚举记不住,用整型就可以了.
d. 只判断两个字符串是否相同.;
- (BOOL)isEqualToString:(NSString *)aString;
匿名对象
- C语言中有 printf(“a+b=%d”, sum(a,b)); 这种用法, 即当函数值只需要使用一次时, 这时候, 不需要单独声明一个变量来存储函数的返回值
- OC中也有这类情况, 即当对象成员只需要使用一次时, 这时候, 就不再单独的声明一个类指针来指向new的对象了, 直接在需要对象成员的地方使用就行.
1 [LHPerson new]->_name = @“jack”; 2 // 这里是new了一个匿名对象, 指定其_name值是jack, 但是在这句语句以后就不能继续使用这个jack了 3 [[LHPerson new] sayHi]; 4 // 这里是new 了一个匿名对象来调用LHPerson 类中的 sayHi 方法 5 [LHPerson new]->_name = @“jack”; 6 [LHPerson new]->_name = @“jack”; // 两行new的不是同一个对象
封装
- 在整个面向对象编程的过程中, 我们需要关心的并不是类是怎么声明和实现的, 方法是怎么声明和实现的, 只需要关心功能有没有得到实现, 类或者方法怎么用, 有什么用
- 并且很多时候, 某些属性的需求的取值范围和其所属的数据类型有冲突(比如age这种属性, 就算是一个unsigned char最大值也是255, 与实际逻辑不符), 并且在给属性赋值的时候再来写一个逻辑判断在语法和实际工作量上也是不现实的
- 需求分析
- 不能允许随意的给属性赋值
- 解决方法, 类属性不设置为@public
- 不能允许在调用类的人去写逻辑判断
- 解决方法, 在类声明的时候, 就写好逻辑判断
- 解决方案
- 在类声明的时候, 声明另外一个方法: 专门用来为对象的属性赋值 setter
- 因为需要访问到属性, 所以只可能是对象方法
- 因为是在判断以后为属性赋值, 所以也不需要返回值
- 有且仅有一个参数, 即需要被赋值的属性, 参数类型即属性的类型
- 在方法内, 进行逻辑判断, 如果满足属性要求就赋值, 如果不满足, 那么就赋默认值
- 外界如果再想给这个属性赋值, 或者访问, 就不能够直接进行了, 只能通过调用这个方法来进行复制
- 再声明一个方法来专门返回对象的属性的值
- 同样也只能是对象方法
- 是返回属性的值, 所以是没有参数, 只有返回值
- 返回值类型即属性的类型
- 方法内容就是一个return
- 同样外界也只能通过调用这个方法来得到属性值