一、ARC
ARC 是一种编译器特性!而不是IOS运行时特性,和JAVA中得垃圾回收机制完全不一样
ARC是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的retain、release、autorelease语句。你不再需要担心内存管理,因为编译器为你处理了一切
ARC规则:只要还有一个强指针变量指向对象,对象就会保持在内存中
弱指针指向的对象被回收后,弱指针会自动变为nil指针,不会引发野指针错误
使用注意:
1、不允许调用release、retain、retainCount;
2、允许重写dello方法,但是重写dello方法中不允许[super delloc];
3、@property参数:
strong :代表创建的 _成员变量 是一个强指针,类似于原来的retain,(适用于OC对象)
weak :代表创建的 _成员变量 是一个若指针,类似于原来的assgin,(适用于OC对象)
assign :这个适用于非OC对象,比如 int型、long型等等
4、以前的retain要改为strong
5、假如出现循环引用的用法,那么就要一端用strong一端用weak
例如:一条狗有一个主人,一个主人有一条狗!
- <p>
- @interface Dog : NSObject
- @property (nonatomic,weak) Person *person; // 狗拥有一个主人对象,这个指针是一个弱指针,
- @end</p><p>@interface Person : NSObject
- @property (nonatomic,strong) Dog *dog; // 人拥有一个狗对象,这个指针是一个强指针,
- @end</p><p>@implementation Person
- @end</p><p>@impleme</p>
二、block
block和函数很像,就是保存代码的一种方式:
1、可以保存代码;
2、有返回值;
3、有形参;
4、调用方式一样
- <p><p>//不带形参的block,如果没有形参可以省略后面的小括号
- void (^myblock)() = ^{
- NSLog(@“我的BLOCK”);
- };</p><p>//带形参的block
- //带两个形参的block求两个int型数据的和
- int (^heblock)(int,int) = ^(int a, int b){
- return a + b;
- };</p><p>//用一个block输出n条横线
- void (^shuchu)(int) = ^(int n){
- for(int i= 0;i<n;i++)
- NSLog(@“———————”);
- };</p>
利用typedef定义block类型
- <p><p>typedef int (^myblock)(int, int);</p><p>myblcok he = ^(int a, int b){
- return a + b;
- };</p><p>int c = he(19,9); // 将19和9的和赋值给c;</p>
总结:
1>如何定义block
int (^heblock)(int,int);
void (^myblock)();
2>如何通过block封装代码
^{NSLog(@“我的BLOCK”);};
3>block访问外面的变量
*block内部可以访问外面的变量
*默认情况下block不能修改外面的局部变量
*给局部变量加上_block关键字,这个局部变量就可以在block内部修改
如: int a = 11;
_block int b = 12;
上面的两个变量a和b只有b能够在block中被修改!
4、利用typedef定义block变量
typedef int (^myblock)(int, int);
上面定义一个block变量后,以后就可以利用my block来直接定义block变量了
如:
- <p>
- myblock a,b;
- myblock c;</p><p>b = ^(int a, int b){
- return a * b;
- };// 注意这个大括号背后的分号不能!因为这是类似一个赋值运算!</p><p>myblock d = ^(int a, int b){
- return a * b;
- };</p>
三、协议
协议 @protocol 用来声明一堆方法(不能声明成员变量)
协议就是用来声明方法的,只要某个类遵守这个协议,就拥有了这个协议中方法的声明!
注意:只要父类遵守了某个协议,那么子类也拥有了某个协议
: 继承父类
<> 遵守协议
协议的参数:
- <p>
- @required // 必须实现,不实现就会报错</p><p>@optional // 不要求必须实现,不实现不会有警告</p><p>@protocol MyPortocol <NSObject>// 所有的协议都要遵守基协议
- - (void)test1;</p><p>@required
- - (void)test2;
- - (void)test3;</p><p>@optional
- - (void)test4;
- - (void)test5;</p><p>@end
- // @required @optional关键字多数是用于程序员之间的交流,
- // 还有就是用于代理模式
- // 一个类可以遵守多个类</p><p>@interface 类名 : 父类 <协议1,协议2> // 这个类就拥有了这两个协议所有的方法</p>
- //基协议:任何协议都遵守的一个协议 NSObject
- //基协议就类似类的定义中的父类,简单的说就是协议也可以遵守某个协议
- // 如果一个协议遵守了某个协议,那么这个协议就拥有了遵守协议的所有方法声明。
- @protocol MyProtocol1 <MyProtocol>
- - (void)test;
- @end
上面的例子中MyProtocol1就拥有了 MyProtocol协议中所有的方法声明
限制对象类型:
- <p>
- // 限制某一个指针变量只能保存遵守某种协议的对象;</p><p>Dog<MyProtocol> *dog; // 这个dog只能保存继承Dog类且遵守了MyProtocol协议的对象</p><p>
- @interface Dog : NSObject <MyProtocol></p><p>@property (nonatomic, strong) id<MyProtocol2> mm; // 创建一个对象成员变量,只能保遵MyProtocol2协议的对象
- @end</p>
协议的提前声明
- <p><p>@protocol XXXXX; //声明XXXX是一个协议,但是如果要用到这个协议内的声明的方法,那么就必须要#import”XXXXX.H”</p><p>// 以后在.h文件中都要用@class/@protocol来声明是个类/协议!
- //因为这样子的效率比较高,当要用到这个类的具体内容/协议的具体声明的时候才#import“”/< ></p>
小结:牢牢记住下面的用法
1、协议的定义
@protocol 协议名称<NSObject>
// 方法的声明
@end
2、如何遵守协议
1>类遵守协议
@interface 类名 : 父类名<协议1,协议2>
@end
2>协议遵守协议
@protocol 协议名称<协议1,协议2>
@end
3、协议中方法的声明关键字
1>@required(默认)
要求实现,如果没有实现就会发出警告
2>@optional
不要求必须实现,不实现不会有警告
4、定义一个变量的时候,限制这个变量保存的对象遵守某个协议
类名<协议名称> *变量名;
Dog<MyProtocol> *dog;
id<协议名称> 变量名;
id<MyProtocol> dog;
如果没有遵守对应的协议,编译器会报出警告
5、@property中声明的属性也可以用一个遵守某个协议来限制
@property <nomotomic,strong> Dog<MyProtocol> *dog;
@property <nomotomic,strong> id <MyProtocol> dog;
注意!!假如编译器的警告给某句代码加了一根横线,那么这个警告就是必须要修复的严重警告
6、协议可以定义在其他文件也可以定在某个类中
//当某个协议只需要某个类遵守的时候就可以和这个类的声明写在同一个文件中;
//当某个协议只需要多个类遵守的时候就要将协议单独写在一个文件中
7、分类也可以定义在单独的.h和.m文件中,也可以定义在原来的类中
//注意!!一般情况下都是定义在单独的文件中!定义在原来类中只要求看懂就行了!
//因为假如定义在原来的类的文件中,何必建分类勒!是不?
代理设计模式(协议的应用)
定义一个类拥有某个成员变量(是对象)的时候,限制这个对象必须要遵守特定的某个协议,那么我这个类写好以后就根本不用动了。我只接受遵守这个协议的成员变量,这样子我方法实现里面就按照这个协议中我所需要的方法直接调用就行了,不用关心以后这个成员变量会变成谁!
例如:
//创建一个协议,协议里面有查询票价和票数量的两个方法
// Dailixieyi.h文件
- <p>
- #import <Foundation/Foundation.h>
- @protocol Dailixieyi<NSObject>
- - (int)piaoShu;</p><p>- (int)piaoJia;
- @end</p>
- <p>// Daili1.h文件
- #import <Foundation/Foundation.h>
- #import “Dailixieyi.h”</p><p>@interface Daili1 : NSObject <Dailixieyi></p><p>@end</p
- <p>// Daili1.m文件
- #import <Foundation/Foundation.h>
- #import “Daili1.h”</p><p>@implementation Daili1
- - (int)piaoShu
- {
- return 15;// 假设返回还有15张票
- }</p><p>- (int)piaoJia
- {
- return 150;// 假设返回的票价是50元
- }
- @end</p>
————————————————————————————————————————————————————————————
- <p>//GuKe.h文件
- #import <Foundation/Foundation.h>
- #import “Dailixieyi.h”
- //注意!这里你只是拥有了这个协议,但是你想使用某个类的时候还得#import这个类的声明!
- //这种设计模式只关心我需要某个类的时候假如这个类的声明就可以了
- @interface GuKe : NSObject</p><p>@property (nonatomic,strong) id<Dailixieyi> daili;// id类型不管什么对象我都能接收但是必须要符合Dailixieyi这个协议!!
- - (void)maiPiao;
- @end</p>