单例模式和block
在ios中最常见的单例模式和代理模式。(设计模式)
1单例模式的作用:
在一个程序的运行过程中,一个类只能有一个实例,而且该实例易于提供外界去访问,从而方便的控制实例的个数和节省资源。
2单例模式的使用场合:
在整个应用程序中,共享一份资源(这份资源只是需要要创建初始化一次),这个类创建出来的对象只有一个
因为单例模式在ARC和MRC的条件下写法不同,需要编写2套不同的方案
可以用宏来判断是否为ARC的环境
#if__has feature (objc_arc)
//ARC
#else
//MRC
#endif
在ARC下的实现模式:
//提供一个方法给外界访问
+(instancetype)sharedInfoManager{
//注意这里的线程锁
@synchronized(_instance) {
_instance= [[selfalloc]init];
}
return_instance;
}
+(id) allocWithZone:(struct_NSZone*)zone{
if(!_instance) {
_instance= [superallocWithZone:zone];
}
return_instance;
}
//实现copyWithZone的方法
+(id)copyWithZone:(struct_NSZone*)zone{
return_instance;
}
//非ARC的情况下的
//实现内存管理的方法
-(id)retain {
returnself;
}
-(NSUInteger)
retainCount{
return1;
}
-(onewayvoid)release{
}
-(id)autorelease{
returnself;
}
重写allocWithzone:方法:控制内存的分配,因为alloc内部会调用该方法,每次调用allocwithzone方法,系统会创建一块新的内存空间。
Alloc方法中:永远只分配一块内存。
Init方法:保证所有的某个类的数据都是只加载一次。
Ios中的常见的单例:
[NSFileManagerdefaultManager];
[NSNotificationCenterdefaultCenter]
[NSNull null];
[UIDevicecurrentDevice];
[UIApplication sharedApplication];
[SDImageCachesharedImageCache];
//加速计
[UIAccelerometersharedAccelerometer];
[NSURLSessionsharedSession];
单例的两种官方的写法:
不使用GCD
#import"ServiceManager.h"
staticServiceManager*defaultManager;
@implementationServiceManager
+(ServiceManager*)defaultManager{
if(!defaultManager)
defaultManager=[[self allocWithZone:NULL] init];
returndefaultManager;
}
@end
使用GCD
#import"ServiceManager.h"
@implementationServiceManager
+(ServiceManager *)sharedManager{
staticdispatch_once_t predicate;
staticServiceManager *sharedManager;
dispatch_once(&predicate, ^{
sharedManager=[[ServiceManager alloc] init];
});
returnsharedManager;
}
@end
dispatch_once这个函数,它可以保证整个应用程序生命周期中某段代码只被执行一次!
Block:
定义的格式:
returnType(^blockName)(parameterTypes) = ^(parameters){
Statements
}
返回值类型(^block名称)(参数列表)=^(参数值){执行的代码}
1先定义后赋值
2定义的同时赋值
1.定义block类型的变量直接赋值
返回值类型(^block变量名)(形参) = ^(形参){
return返回值类型;
}
2.使用block类型的变量
block变量名(实参);
记住两个基本,其他的都会记住:
1有参数,有返回值
Int(^myblock)(int,int)= ^(int num1,intnum2)
2无参数,无返回值
Void(^myblock)() = ^(){块}
敏感字眼:1__block2 __weak3 block内部访问外部变量
block内部可以定义和外部同名的变量,此时局部变量可以暂时屏蔽外部变量
给外部的变量加上__block可以在内部修改外部的变量
Block作为方法的参数:(ios中用到最多的)
关于堆block?
Block内部使用了外部的局部变量,block就是堆block这样的方式是”只读的“
block外部的变量加上__block,block内部使用这个局部变量,block就在堆区“可以读写”
书写格式:
-(void)run:(void(^)(int,int))block1;