iOS工作记录9:项目单例(直接拉用)

我就直接用个例子记录:

工程代码记录下来:

//

//  Ticket.h

#import <Foundation/Foundation.h>

@interface Ticket :
NSObject

// 实例化票据的单例

+ (Ticket *)sharedTicket;

// 在多线程应用中,所有被抢夺资源的属性需要设置为原子属性

// 系统会在多线程抢夺时,保证该属性有且仅有一个线程能够访问

// 注意:使用atomic属性,会降低系统性能,在开发多线程应用时,尽量不要资源

// 另外,atomic属性,必须与@synchronized(同步锁)一起使用

// 票数

@property (assign,
atomic) NSInteger tickets;

@end

//

//  Ticket.m

/**

实现单例模型需要做三件事情

1. 使用全局静态变量记录住第一个被实例化的对象

static Ticket *SharedInstance

2. 重写allocWithZone方法,并使用dispatch_once_t,从而保证在多线程情况下,

同样只能实例化一个对象副本

3. 建立一个以shared开头的类方法实例化单例对象,便于其他类调用,同时不容易引起歧义

同样用dispatch_once_t确保只有一个副本被建立。

另外关于被抢夺资源使用的注意事项

在多线程应用中,所有被抢夺资源的属性需要设置为原子属性

系统会在多线程抢夺时,保证该属性有且仅有一个线程能够访问

注意:使用atomic属性,会降低系统性能,在开发多线程应用时,尽量不要资源

另外,atomic属性,必须与@synchronized(同步锁)一起使用

*/

#import "Ticket.h"

static Ticket *SharedInstance;//使用全局静态变量记录住第一个被实例化的对象

@implementation Ticket

// 使用内存地址实例化对象,所有实例化方法,最终都会调用此方法

// 要实例化出来唯一的对象,需要一个变量记录住第一个实例化出来的对象

+ (id)allocWithZone:(NSZone *)zone

{

//
解决多线程中,同样只能实例化出一个对象副本

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

SharedInstance = [super
allocWithZone:zone];

});

return
SharedInstance;

}

// 建立一个单例对象,便于其他类调用

+ (Ticket *)sharedTicket

{

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

SharedInstance = [[Ticket
alloc]init];

});

return
SharedInstance;

}

@end

//

//  MainViewController.m文件

//

#import "MainViewController.h"

#import "Ticket.h"

- (void)viewDidLoad

{

[super
viewDidLoad];

[Ticket
sharedTicket].tickets =
30;//单例使用

}

//=============================================重新介绍以下什么是单例模式================================

IOS 单例模式

(2012-05-31 20:17:53)

转载▼

单例模式顾名思义就是只有一个实例,它确保一个类只有一个实例,并且自行实例化并向整个系统提供这个实例。它经常用来做应用程序级别的共享资源控制。这个模式使用频率非常高,通过一个单例类,可以实现在不同窗口之间传递数据。

在objective-c中要实现一个单例类,至少需要做以下四个步骤:

1、为单例对象实现一个静态实例,并初始化,然后设置成nil,

2、实现一个实例构造方法检查上面声明的静态实例是否为nil,如果是则新建并返回一个本类的实例,

3、重写allocWithZone方法,用来保证其他人直接使用alloc和init试图获得一个新实例的时候不产生一个新实例,

4、适当实现allocWitheZone,copyWithZone,release和autorelease

例子:为RootViewController创建一个单例函数:

static RootViewController *shareRootViewController = nil;

+(RootViewController *)sharedController{

@synchronized(self){

if(shareRootViewController == nil){

shareRootViewController = [[[self alloc] init] autorelease];

}

}

return shareRootViewController;

}

+(id)allocWithZone:(NSZone *)zone{

@synchronized(self){

if (shareRootViewController == nil) {

shareRootViewController = [super allocWithZone:zone];

return  shareRootViewController;

}

}

return nil;

}

NSZone: 简单来说可以把它想象成一个内存池,alloc或者dealloc这些操作都是在这个内存池中操作的,cocoa总是会分配一个默认的nsZone,任何 默认内存操作都是在这个zone上进行的,使用默认zone存在缺陷,因为他是全局范围的,频繁使用会导致内存的碎片化,尤其是大量的alloc和 dealloc的时候,性能上会受到一定影响。因为你完全可以自己生成一个zone并将alloc,copy这些限制在这个zone中。

iOS 创建单例的两种方法

创建一个单例很多办法。我先列举一个苹果官方文档中的写法。

  1. static AccountManager *DefaultManager = nil;
  2. + (AccountManager *)defaultManager {
  3. if (!DefaultManager) DefaultManager = [[self allocWithZone:NULL] init];
  4. return DefaultManager;
  5. }

当然,在iOS4之后有了另外一种写法:

[cpp] view
plain
copy

  1. + (AccountManager *)sharedManager
  2. {
  3. static AccountManager *sharedAccountManagerInstance = nil;
  4. static dispatch_once_t predicate;
  5. dispatch_once(&predicate, ^{
  6. sharedAccountManagerInstance = [[self alloc] init];
  7. });
  8. return sharedAccountManagerInstance;
  9. }

该写法来自 objcolumnist,文中提到,该写法具有以下几个特性:

1. 线程安全。

2. 满足静态分析器的要求。

3. 兼容了ARC

然后我还有点好奇的是dispatch_once,这个函数,没见过啊。

于是就到官方的文档里找找看,是怎么说的。

下面是官方文档介绍:

该方法的作用就是执行且在整个程序的声明周期中,仅执行一次某一个block对象。简直就是为单例而生的嘛。而且,有些我们需要在程序开头初始化的动作,如果为了保证其,仅执行一次,也可以放到这个dispatch_once来执行。

然后我们看到它需要一个断言来确定这个代码块是否执行,这个断言的指针要保存起来,相对于第一种方法而言,还需要多保存一个指针。

方法简介中就说的很清楚了:对于在应用中创建一个初始化一个全局的数据对象(单例模式),这个函数很有用。

如果同时在多线程中调用它,这个函数将等待同步等待,直至该block调用结束。

这个断言的指针必须要全局化的保存,或者放在静态区内。使用存放在自动分配区域或者动态区域的断言,dispatch_once执行的结果是不可预知的。

总结:1.这个方法可以在创建单例或者某些初始化动作时使用,以保证其唯一性。2.该方法是线程安全的,所以请放心大胆的在子线程中使用。(前提是你的dispatch_once_t *predicate对象必须是全局或者静态对象。这一点很重要,如果不能保证这一点,也就不能保证该方法只会被执行一次。)

时间: 2024-08-24 21:59:29

iOS工作记录9:项目单例(直接拉用)的相关文章

iOS 页面间传值 之 单例传值 , block 传值

ios 页面间传值有许多,前边已经分享过属性传值和代理传值,今天主要说一下单例传值和 block 传值 单例传值:单例模式一种常用的开发的模式,单例因为在整个程序中无论在何时初始化对象,获取到的都是同一个对象,对象的属性相同,所以可以用来传值. block 传值 与 代理传值相似,主要用于第二个页面向第一个页面传值,block 传值具体步骤: 在第二个页面: 1.声明: block typedef void(^SendMessagerBlock) (NSString *str); 2.创建方法:

【iOS】ARC-MRC下的单例及其应用

单例的应用十分普遍,单例模式使一个类只有一个实例. *易于供外界访问. *方便控制实例个数,节约系统资源. *OC中的常见单例: 如:UIApplication,  NSNotificationCenter,  NSUserDefaults, NSFIleManager. *应用程序中用到的单例: 如:背景音乐,音效管理等. 一.ARC中实现单例 创建单例的步骤: *1.定义一个全局的静态变量_instance,用来记录“第一次”被实例化出来的对象. *2.重写allocWithZone方法,此

iOS开发中常用的单例

定义:一个类的对象,无论在何时创建.无论创建多少次,创建出来的对象都是同一个对象. 使用场景:当有一些数据需要共享给别的类的时候,就可以把这些数据保存在单例对象中. 关键代码: + (instancetype)allocWithZone:(struct_NSZone *)zone {     static id instance = nil;     if(instance == nil)     {       instance =   [super allocWithZone:zone];

iOS——Swift开发中的单例设计模式(摘译,非原创)

最近在开发一个小的应用,遇到了一些Objective-c上面常用的单例模式,但是swift上面还是有一定区别的,反复倒来倒去发现不能按常理(正常的oc to swift的方式)出牌,因此搜索了一些帖子.可能是xcode或者sdk的问题吧(我相信他们不会把未经测试的代码展示,吧?...),一些帖子中的代码犯了明显的错误,编译失败.于是有了这篇文章,分享给大家. 原作者实现了一种单例,但是红色代码导致非线程安全: 1 class var sharedInstance:TPScopeManager {

工作记录:项目基础库文件BaseFun.py

#!/usr/bin/env python # coding=utf-8 import os import datetime import hmac import base64 import time import requests import filecmp import HTMLTestRunner import urllib2 import hashlib import json import re import redis import psycopg2 import subproce

iOS工作记录10:清理缓存

我们在做项目开发的时候,经常会遇到设置清理缓存的问题,对于新手经常会考虑到什么数据存储啊,内存之类一大堆无用的想法,其实镔哥认为清理工程的缓存是一件非常简单的事情. 不用多说:见代码,立即大悟: @property (nonatomic, strong) UILabel * cachLabel;//显示缓存有多少m 最后节目显示: cell.cachLabel.text = [NSString stringWithFormat:@"(%.2fM)", [self filePath]];

iOS开发之自定义一个单例

这里我使用宏: // .h#define single_interface(class)  + (class *)shared##class; // .m// \ 代表下一行也属于宏// ## 是分隔符 #define single_implementation(class) \ static class *_instance; \ \ + (class *)shared##class \ { \ if (_instance == nil) { \ _instance = [[self allo

iOS设计模式之单例

单例模式的意思就是这个类只有一个实例,这个类就是单例类.在iOS中有不少都是单例NSNull,NSFileManager ,UIApplication,NSUserDefaults ,UIDevice,还有一些第三方也有能用到了这种设计模式例如Afhttpmanger... (1)单例模式的作用 :可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问,从而方便地控制了实例个数,并节约系统资源. (2)单例模式的使用场合:在整个应用程序中,共享一份资源(这份资源只需要创建初始化1次

iOS 开发中的单例

在iOS开发中经常会用到单例,比如每个iOS程序本身就是一个单例,在比如进行个人偏好设置存储的时候用的也是一个单例.那我们如何自己来写一个单例类呢,用自己的单例对象呢?下面是我写的一个单例的头文件里的代码,这个文件主要是一些宏.使用步骤写的都很详细,ARC或MRC都可以使用. //  Singleton.h //  单例的宏 /* 使用方法 1:包含这个头文件 2:在.h文件总包含 singleton_h(name) 里面的name是你想要生成单例对象时的名字 3:在.m文件中包含 single