UIday1202:单例

单例对象
 单例。单:唯⼀性。例:实例对象。即使用某个类创建的对象是程序中唯⼀的实例对象。
 注:通常每次使⽤ alloc 创建的是不同的对象。
 如果⼀个类只能创建⼀个对象,称为单例类。单例类可以是⼯具类,视图类,控制器类。
 
 使用场景
 某些时候,程序中的多个类需要使⽤同⼀个变量。如何处理?将变量定义在单例类中,则所有类在操作这个变量时都很⽅便容易。
 思考:
 通讯录的列表⻚面、添加⻚面、编辑⻚面需要同⼀个数据源,如何提供数据源才更⽅便操作?
 导航控制器从 firstVC 展⽰到 thirdVC ,如何将值从 firstVC 传⼊ thirdVC ?
 
 使用方法:
 定义单例类。
 定义创建单例对象的方法 ( 类⽅法 ) 。
 根据需要实现伪单例或完整单例。
 
 注意:
 操作单例对象的变量存储在静态区,程序关闭后由系统⾃动回收。
 单例对象存储在堆区,不释放,程序关闭后由系统⾃动回收。
 变量和单例对象的生命周期与程序同步。
 
 优势
 在内存中只有⼀个对象,节省内存空间。
 避免频繁的创建销毁对象,可以提⾼性能。
 避免对共享资源的多重占⽤。
 可以全局访问。
 降低模块之间的耦合度,降低代码的复杂度。
 
 单例模式
 单例模式是⼀种设计模式。

 实现:定义⼀个单例类,保证程序中这个类只能创建唯⼀的实例对象,实现资源共享。

//*************************************************

单例
 在程序中只创建一个对象,程序当中有很多对象,我们只需要一个就可以了
 单例传值,类似于一个仓库的存在
 单例还有作用是保存数据,临时保存数据
 单例还可以做工具,学网络解析的时候,可以写一个解析类
 
 单例的创建:SingleHendel类中的三步操作,目前不涉及多线程,所以这种方法现在是没问题的,如果涉及到多线程的话还需要做一些其他事情
 
 单例传值  
 用单例解决一类问题 称为一种设计模式,叫单例模式


自己写程序的话  建议用伪单例
 如果写的是第三方框架  建议使用完整单例 (完整单例需要重写很多方法)
 今天学的是伪单例

//*************************************************

//++++++++++++++++++++++++++++++++

非常重要的数据共享的方法
什么是单例:
    其实就是c中的全局变量 单例和全局变量是等同的
    在整个程序生命周期内,该对象只有一份存在内存中
    可以在多个对象之间共享数据
什么是单例设计模式
    单独的一个对象,很多指针指向它
多个对象之间共享数据

典型的单例写法:

//创建一个对象

static id sharedMyManager;

+(id)sharedThemeManger{
    if(sharedMyManager == nil){
        //第一次进入调用,把s存于全局变量中
        sharedMyManager = [[self alloc]init];
    }
    //第2次,第3次。。。。都会使用第一次的创建好的变量
    return sharedMyManager;
}



//这种写法有个问题:如果多个线程同时调用这个函数 ,可能会创建多个对象,这样有可能会造成内存泄露问题,所以需要我们改一下.

//1 改成一个加锁的方式:
+(id)sharedThemeManger{
//@synchronized(self)让这段代码处于atomic状态
//如果多个线程进入这段代码 这段代码只能是一个线程执行
    @synchronized(self){
    if(sharedMyManager == nil){
        sharedMyManager = [[self alloc]init];
    }
    }
    return sharedMyManager;
}

//2 第一次实例化创建Lock free 免锁写法
+(voidq)initialize{
    static BOOL initialized = NO;
    if(initialized == NO){
        initialized = YES;
        sharedMyManager = [[self alloc]init];
    }
}

//3 GCD写法:(推荐使用)
+(id)sharedManager{
    static dispatch_once_t onceToken;
    //dispatch_once 就是保证了blocks只能执行一次
    dispatch_once(&onceToken,^{
        if(s == nil){            
            s = [[[self class]alloc]init];
        }
    });
    return sharedMyManager;
}



//单例的正确调用方法:
ThemeManager * tm2 = [ThemeManager sharedThemeManager];

//单例方法的调用要避免以下形式(虽然完整的单例写法中允许这样写,但是不建议这样):
ThemeManager * tm4 = [[ThemeManager alloc]init];
ThemeManager * tm5 = [tm4 copy];

//要完整的写一个单例,需要重载下面五个方法(ARC模式不需要下面三个)
+(id) allocWithZone:(NSZone *)zone;
+(id) copyWithZone:(NSZone *)zone;
-(id) retain;
-(void) release;
-(void) autorelease;

+(id) allocWithZone:(NSZone *)zone{
    //alloc 会用
    return [[self sharedThemeManager]retain];
}
+(id) copyWithZone:(NSZone *)zone{
    return self;
}
-(id) retain{
    return self;
}
-(oneway void) release{
    
}
-(void) retainCount{
    //对计数器返回一个最大数
    return UINT_MAX;
}
-(id)autorelease{
    return self;
}


单例不建议使用alloc创建,直接用类方法创建


//++++++++++++++++++++++++++++++++

=================================



AppDelegate.m

#import "AppDelegate.h"
#import "RootViewController.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    
    RootViewController * rootVC = [[RootViewController alloc]init];
    
    UINavigationController * rootNC = [[UINavigationController alloc]initWithRootViewController:rootVC];
    
    self.window.rootViewController = rootNC;
    
    return YES;
}

@end


RootViewController.m

#import "RootViewController.h"
#import "SingleHandle.h"
#import "NextViewController.h"

@interface RootViewController ()

@property(nonatomic,strong)UITextField * rootTextField;

@end

@implementation RootViewController

//***
-(void)viewWillAppear:(BOOL)animated{
    self.rootTextField.text = [SingleHendel shareSingle].aString;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor yellowColor];
    
/*
#warning test
    
    SingleHandle *s1 = [SingleHandle shareSingle];
    SingleHandle *s2 = [SingleHandle shareSingle];
    
    //打印看地址是否一样 一样说明创建出来的对象是同一个
    NSLog(@"s1:%p",s1);
    NSLog(@"s2:%p",s2);
 */
    
    //创建textField
    self.rootTextField  =  [[UITextField alloc]initWithFrame:CGRectMake(50, 80, 250, 50)];
    
    self.rootTextField.backgroundColor = [UIColor whiteColor];
    
    [self.view addSubview:_rootTextField];
    
    
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    NextViewController * nextVC = [[NextViewController alloc]init];
    
    // ****给单例赋值
    [SingleHandle shareSingle].aString = self.rootTextField.text;
    
    [self.navigationController pushViewController:nextVC animated:YES];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end

NextViewController.m

#import "NextViewController.h"
#import "SingleHandle.h"

@interface NextViewController ()

@property(nonatomic,strong)UITextField * nextTextField;

@end

@implementation NextViewController

-(void)viewWillAppear:(BOOL)animated{
    //****从单例中取值
    self.nextTextField.text = [SingleHandle shareSingle].aString;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor greenColor];
    
    //创建nextTextField
    self.nextTextField = [[UITextField alloc]initWithFrame:CGRectMake(50, 80, 250, 50)];
    self.nextTextField.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:_nextTextField];
    
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    //****POP之前 给单例属性赋值
    [SingleHandle shareSingle].aString = self.nextTextField.text;
    [self.navigationController popToRootViewControllerAnimated:YES];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end

SingleHandle.h

#import <Foundation/Foundation.h>

@interface SingleHandle : NSObject

@property(nonatomic,copy)NSString * aString;

//创建单例第一步
+(instancetype)shareSingle;


@end

SingleHandle.m

#import "SingleHandle.h"

//第二步 定义静态变量 (生命周期是整个程序)
static SingleHandle* sh = nil;

@implementation SingleHandle

//创建单例第一步 实现方法
//伪单例 (和这个伪单例对应的是完整单例)
+(instancetype)shareSingle{
    
    //第三步 判断是否为空,是 则创建
    if (sh == nil) {
        sh = [[SingleHandle alloc]init];
    }
    
    return sh;    
}

@end




//

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值