======文档更新状态=====
2015-12-24:发布
==================
day10-[2015-12-23]
一、关于ARC的补充
1.和属性修饰符对应的有3个对象指针修饰符,均以2个下划线开头,再加上相应的属性修饰符名称
2.在ARC中,将一个对象指针赋给另一个对象指针,默认采用__strong方式(相当于MRC下调用retain方法),可以指定__weak、__unsafe_unretained(相当于MRC下直接赋值)
// YYBook.h
#import <Foundation/Foundation.h>
@interface YYBook : NSObject
@property (nonatomic,copy)NSString* title;
@property (nonatomic,assign)int price;
-(instancetype)initWithTitle:(NSString*)title price:(int)price;
@end
// YYBook.m
#import "YYBook.h"
@implementation YYBook
-(instancetype)initWithTitle:(NSString *)title price:(int)price{
if (self=[super init]) {
self.title=title;
self.price=price;
}
return self;
}
-(void)dealloc{
NSLog(@"Book %@ dealloc",_title);
}
-(NSString *)description{
return [NSString stringWithFormat:@"Book %@ %d",_title,_price];
}
@end
// main.m
#import "YYBook.h"
//main函数本身就是一个最大的ARP
int main_arc(int argc, const char * argv[]) {
//__strong、 __weak、 __unsafe_unretained
__weak YYBook* bk2=nil;
@autoreleasepool {
YYBook* bk=[[YYBook alloc]initWithTitle:@"iOS" price:20];
bk2=bk;
NSLog(@"bk:%@",bk);
}
NSLog(@"bk2:%@",bk2);
NSLog(@"end of main.");
return 0;
}
执行结果:
2015-12-24 00:13:21.775 1223[2255:96860] bk:Book iOS 20
2015-12-24 00:13:21.777 1223[2255:96860] Book iOS dealloc
2015-12-24 00:13:21.778 1223[2255:96860] bk2:(null)
2015-12-24 00:13:21.778 1223[2255:96860] end of main.
二、异常Exception
1.概念:运行时错误,一般由运行环境造成,有别于主观原因造成的语法、算法错误
2.语法结构:@try{
//有可能产生异常的代码
}@catch(异常类型指针){
//产生异常时的处理代码
}@finally{
//不管是否有异常产生都有执行的代码
}
3.执行流程:try块中一旦有代码产生异常,则该行及其后的代码都不再执行,转到catch块中执行,执行完后进入finally块执行,执行完后如果还有代码则继续执行;try块中全部代码都没有产生异常,则跳过catch直接进入finally块执行,执行完后如果还有代码则继续执行;finally权限较高,即使在try或catch中有return,也必须等finally执行完才能返回,除非强制退出exit(0)函数;所以不建议在finally中有return语句
4.抛出异常@throw的用法,在需要抛出异常的方法或函数中使用该指令,后面跟上一个NSException对象(可以使用规范的类方法或初始化方法)
5.自定义异常
A.定义NSException的子类
B.根据需要定义、重写相关方法
C.抛出自定义异常和抛出NSException相同
D.捕捉:注意顺序(父子层次关系越低的越靠前,NSException肯定写在最后)
6.OC的异常处理机制不适用于C的函数,但可以通过其他方式来辅助判断是否出现异常
// YYDemo.h
#import <Foundation/Foundation.h>
#import "YYAgeException.h"
@interface YYDemo : NSObject
@property (nonatomic,assign)int price;
@property (nonatomic,assign)int age;
-(void)method1;
-(void)method2;
@end
// YYDemo.m
#import "YYDemo.h"
@implementation YYDemo
-(void)method1{
NSLog(@"Method1 in YYDemo");
}
/**
* 如果参数为负数,抛出reason为价格偏低的信息
* 如果参数大于1000,抛出reason为价格偏高的信息
*
* @param price
*/
-(void)setPrice:(int)price{
if (price < 0){
@throw [NSException exceptionWithName:@"价格异常" reason:@"价格偏低" userInfo:nil];
}
else if (price>1000){
@throw [NSException exceptionWithName:@"价格异常" reason:@"价格偏高" userInfo:nil];
}
else{
_price=price;
}
}
-(void)setAge:(int)age{
if (age<0) {
@throw [YYAgeException ageExceptionWithReason:@"年龄小于0"];
}
else if (age>150){
@throw [YYAgeException ageExceptionWithReason:@"年龄大于150"];
}
else{
_age=age;
}
}
@end
// YYAgeException.h
#import <Foundation/Foundation.h>
/**
* 描述年龄超出范围的情况
*/
@interface YYAgeException : NSException
-(instancetype)initWithReason:(NSString *)reason;
+(instancetype)ageExceptionWithReason:(NSString *)reason;
@end
// YYAgeException.m
#import "YYAgeException.h"
@implementation YYAgeException
-(instancetype)initWithReason:(NSString *)reason{
return self=[super initWithName:@"YYAgeException" reason:reason userInfo:nil];
}
+(instancetype)ageExceptionWithReason:(NSString *)reason{
return [[self alloc]initWithReason:reason];
}
@end
// 异常执行顺序
// test_exception1.m
#import "YYDemo.h"
int testReturn(){
YYDemo* d1;
@try {// 注意这里的try块不管是否有异常testReturn()都会返回3<打开此函数的注释验证>所已不应该在@finally
// 中使用return语句(如果我想正常结束返回1不正常结束返回2,因为在finally中加了return就实现不了我的想法)
d1=[YYDemo new];
[d1 method1];//1.
// [d1 method2];
return 1;// return 1 之前会调用finally
}
@catch (NSException *ex) {
NSLog(@"产生异常了");
return 2;
}
@finally {
NSLog(@"最终执行的代码");
// return 3;
}
NSLog(@"testReturn结束");
return 0;
}
int main_ex1(){
int ret=testReturn();
NSLog(@"ret=%d",ret);
return 0;
}
// 几点注意
// 1>上面代码演示异常执行顺序
//try块中一旦有代码产生异常,则该行及其后的代码都不再执行,转到catch块中执行,执行完后进入finally块执行,执行完后如
//果还有代码则继续执行;try块中全部代码都没有产生异常,则跳过catch直接进入finally块执行,执行完后如果还有代码则继续
//执行;finally权限较高,即使在try或catch中有return,也必须等finally执行完才能返回,除非强制退出exit(0)函数;所以
//不建议在finally中有return语句
//2>注意事项
//a)@try是异常处理中必须出现的,@catch和@finally是可选的,但至少出现一个
//b)@finally是无论有没有产生异常、无论产生的异常是否捕捉到都要执行的,甚至return也不能影响其执行
//c)在@try块中定义的变量是无法在@catch和@finally中使用的
//d)不应该在@finally中使用return语句
// 抛出异常@throw的用法
// test_ex2.m
#import "YYDemo.h"
int main_ex2(){
YYDemo* d=[YYDemo new];
@try{
[d method2];
d.price=-100;// 这里会抛出异常
}
@catch(NSException* ex){
NSLog(@"ex.name:%@",ex.name);
NSLog(@"ex.reason:%@",ex);
}
@finally{
NSLog(@"最终处理");
}
return 0;
}
// 自定义异常
// test_ex3.m
#import "YYDemo.h"
int main_ex3(){
YYDemo* d=[YYDemo new];
@try {
// 注意下面多处有异常但只有第一个发生异常的地方会被try到
d.age=860;
d.price=-20;
[d method1];
[d method2];
}
// 注意下面有两个catch,注意顺序(父子层次关系越低的越靠前,NSException肯定写在最后)
@catch (YYAgeException* aex){// 小网捕捉放前面
NSLog(@"年龄产生异常:%@",aex);
}
@catch (NSException *exception) {// 大网捕捉放后面
NSLog(@"ex.name:%@",exception.name);
NSLog(@"ex:%@",exception);
}
@finally {
NSLog(@"finally");
}
return 0;
}
//自定义异常
//A.定义NSException的子类
//B.根据需要定义、重写相关方法
//C.抛出自定义异常和抛出NSException相同
//D.捕捉:注意顺序(父子层次关系越低的越靠前,NSException肯定写在最后)
// OC的异常处理机制不适用于C的函数,但可以通过其他方式来辅助判断是否出现异常
// test_ex4.m
#import <Foundation/Foundation.h>
int main_ex4(){
char chs[1000]={0};
int a;
scanf("%s",chs);
a=atoi(chs);//ASCII to Int
NSLog(@"a=%d",a);
NSString* s1=[NSString stringWithUTF8String:chs];
NSString* s2=[NSString stringWithFormat:@"%d",a];
if ([s1 isEqualToString:s2]) {
NSLog(@"ok");
}
else{
NSLog(@"input error");
}
return 0;
}
三、包装类
1.作用:将C语言的基本类型封装成OC对象,以供Foundation框架库使用
2.不同数据类型封装方法不同,每个封装方法都有对应的拆包方法
3.NSNumber主要用于包装数值类型,如:int、float、char等
4.NSValue主要用于包装指针、特定结构体类型,如:Size、Point
// 演示包装类
// test_number.m
#import <Foundation/Foundation.h>
int main(){
int a=10;
NSNumber* n1=[NSNumber numberWithInt:a];
NSLog(@"n1=%@,n1=%d",n1,[n1 intValue]);
NSPoint pt={10,20};
NSRect rt={pt,{100,80}};
NSValue* v1=[NSValue valueWithRect:rt];
NSLog(@"v1:%@",v1);
NSNumber* n2=@(100);
NSNumber* n3=@(a);//@a是错的(@后直接加英文编译系统认为它可能是摸个类似与@interface的指令)
NSLog(@"n2:%@,n3:%@",n2,n3);
return 0;
}
// 运行结果
//2015-12-24 01:20:24.591 1223[2497:120787] n1=10,n1=10
//2015-12-24 01:20:24.592 1223[2497:120787] v1:NSRect: {{10, 20}, {100, 80}}
//2015-12-24 01:20:24.592 1223[2497:120787] n2:100,n3:10
//Program ended with exit code: 0
===============EOF=====================