当前位置: 首页 > news >正文

佛山找人做网站现在搜索引擎哪个比百度好用

佛山找人做网站,现在搜索引擎哪个比百度好用,网站和其他系统对接怎么做,做网站销售好累【iOS】单例模式 什么是单例模式? 定义 单例模式,简单地说就是一个类只对应一个对象,每次使用这个类时,都只能获取到那一个对象。它的详细定义如下: 如果一个类始终只能创建一个实例,则这个类被称为单例…

【iOS】单例模式

什么是单例模式?

定义

单例模式,简单地说就是一个类只对应一个对象,每次使用这个类时,都只能获取到那一个对象。它的详细定义如下:

如果一个类始终只能创建一个实例,则这个类被称为单例类。 有一个全局的接口来访问这个实例。当第一次载入的时候,它通常使用延时加载的方法创建单一实例。 在程序中,一个单例类在程序中只能初始化一次,为了保证在使用中始终都是存在的,所以单例是在存储器的全局区域,在编译时分配内存,只要程序还在运行就会一直占用内存,在APP结束后由系统释放这部分内存 系统方法中,有未知的自动释放池,如果一个对象进行自动释放的话,又可能进入未知的自动释放池,出现内存问题。这就是单例模式不能自动释放的原因

特点

1.单例是一个类,创造出来的对象叫单例对象

2.单例对象使用类方法创建

3.单例一旦被创建,程序结束才会释放,也就是说,单例只初始化一次

4.单例不用程序员管理内存,内存随程序关闭而释放

为什么使用单例模式?

有时候我们需要一个全局的对象,而且要保证全局有且只有一份即可,这时候就需要用到单例设计模式,需要注意:在多线程的环境下做好线程保护。 一般在程序中,经常调用的类,如工具类、公共跳转类等都会采用单例模式

常见的单例模式

在OC语言中,有一些原生的单例类

UIApplication应用程序实例类
NSNotificationCenter消息中心类
NSFileManager文件管理类
NSUserDefaults应用程序设置
NSURLCache请求缓存类
NSHTTPCookieStorage应用程序cookies池

如何使用单例模式?

static关键字

在了解如何使用单例模式之前,我们先来了解一个与之相关的属性修饰关键字——static

static关键字用于修饰局部变量、全局变量和函数。修饰局部变量时,表示该局部变量存储在静态区,修饰全局变量时,表示限制该全局变量只能在当前文件中访问,修饰函数时,则表示限制函数只能在当前源文件中使用。

静态内存存储区在整个程序运行期间都存在

我们需要用static关键字来修饰单例变量,将变量限制在当前类的文件,否则在其他类中可以使用extern来拿到这个单例并修改

创建单例

我们来试着创建一个单例

#import <Foundation/Foundation.h>NS_ASSUME_NONNULL_BEGIN@interface singleton : NSObject
+ (id)instance;
@endNS_ASSUME_NONNULL_END#import "singleton.h"@implementation singleton
static id instance = nil;+ (id)instance {if (!instance) {instance = [[super allocWithZone:NULL] init];}return instance;
}@end#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "singleton.h"int main(int argc, char * argv[]) {NSString * appDelegateClassName;@autoreleasepool {NSLog(@"singleton:%d",[singleton instance] == [singleton instance]);NSLog(@"%d",[singleton instance] == [[singleton alloc] init]);}return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}

运行后得到以下结果:

我们发现,当使用自定义的类方法创建对象时,的确实现了我们想要的效果,创建出了单例。但是,当使用alloc init创建对象时,得到的并不是单例,与使用类方法创建的对象也并不相同。

这个时候我们就需要重写alloc init方法,来保证无论使用什么方法创建,这个类始终只有一个对象。这时我们只需重写allocWithZone:方法就可以了。

我们平时在初始化对象时使用的方法[[Class alloc] init],其实做了两件事,alloc方法为对象分配内存空间,init是对对象的初始化(包括设置成员变量初值等工作)。而给对象分配内存空间,除了alloc方法,还有一个方法就是allocWithZone:。使用alloc方法时,其实也是调用了allocWithZone方法的,所以只需要在allocWithZone里重写,就可以覆盖所有会生成新的实例的方法

这里的allocWithZone:方法,它的参数是被忽略的,正确的做法是传nil或者NULL。

此外,为了防止copy方法生成新的实例,还要重写copyWithZone和mutableCopyWithZone。

​#import "singleton.h"@implementation singleton
static id instance = nil;+ (id)instance {if (!instance) {instance = [[super allocWithZone:NULL] init];}return instance;
}+ (instancetype)allocWithZone:(struct _NSZone *)zone{return instance;
}
-(id)copyWithZone:(NSZone *)zone{return instance;
}-(id)mutableCopyWithZone:(NSZone *)zone{return instance;
}@end

懒汉模式

创建单例有两种模式,分别是懒汉模式和饿汉模式。这两种模式的区别就在于在什么时候去创建对象,懒汉模式就是在第一次用到类的时候才会实例化,饿汉模式就是在类加载的时候就进行实例化。下面先介绍一下懒汉模式

懒汉模式一般用于访问量较小的时候,用时间换空间。通俗地说,懒汉模式就像一个大懒虫,这个懒虫现在有很多穿过的脏衣服,但是他却不打算洗这些衣服,等到实在没衣服穿了,他才会去洗这些衣服。

在使用懒汉模式的时候,要注意保证线程的安全性。

多线程和单线程

线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,也就是说不同的线程可以执行同样的函数。

多线程是指程序中包含多个执行流,也就是在一个程序中可以同时运行多个不同的线程来执行不同的任务

加锁

在单线程中,我们上面所用到的创建单例的方法其实就是懒汉模式,可以直接使用上面的方法来创建懒汉模式,而在多线程中,为了确保线程安全,我们可以用@synchronized来加锁,@synchronized可以防止不同的线程同时执行同一段代码,因此加锁后每次访问该代码就都只能一个行程进行访问。

#import "FirstMethod.h"@implementation FirstMethod
static id instance = nil;
+ (instancetype)instance {@synchronized (self) {if (!instance) {instance = [[super allocWithZone:NULL] init];}}return instance;
}
@end

这一段代码可以在确保线程安全的情况下实现单例,但是我们细看会发现调用insrance方法后,如果instance已经存在,可以直接将instance作为返回值传递出去,没有必要进入锁。于是我们加锁之前先做一次判断

#import "FirstMethod.h"@implementation FirstMethod
static id instance = nil;
+ (instancetype)instance {if (!instance) {@synchronized (self) {if (!instance) {instance = [[super allocWithZone:NULL] init];}}}return instance;
}
@end

注意:这里内层的if不能省略,因为如果省略了内层的if,只是对对象的创建和初始化加了锁,而不是对创建单例过程加锁,也就是说有可能会有两个线程同时进入外层的if,然后先后一个一个执行alloc init,这样就可能导致创建出两个不一样的对象。

GCD的dispatch_once

GCD:全称是Grand Central Dispatch,可译为“牛逼的中枢调度器”,是苹果公司为多核的并行运算提出的解决方案,会自动利用更多的CPU内核(比如双核、四核),自动管理线程的生命周期(创建线程、调度任务、销毁线程),程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码。

另一种确保线程安全的方法就是使用GCD的dispatch_once来创建单例

#import "singleton.h"@implementation singleton
static id instance = nil;+ (id)instance {static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{instance = [[super alloc] init];});return instance;
}+ (instancetype)allocWithZone:(struct _NSZone *)zone{return instance;
}
@end

下面解释一下dispatch_once是怎样确保线程安全并创建单例的。

我们看到上述代码中出现了dispatch_once_t变量和dispatch_once函数

dispatch_once_t变量

这里的intptr_t长度是所在平台的位数,用来存放地址。

dispatch_once函数

dispatch_once无论单线程还是多线程,都只执行一次,在安全的前提下也保证了性能,同时实现了单例的创建。

当onceToken为0时,线程执行dispatch_once的block中的代码

当onceToken为-1时,线程跳过dispatch_once的block中的代码

当onceToken为其他值时,线程被阻塞,等待onceToken值改变

饿汉模式

#import "singleton.h"@implementation singleton
static id instance = nil;+ (void)load {[super load];instance = [[self allocWithZone:NULL] init];
}+ (id)instance {instance = [[self allocWithZone:NULL] init];return instance;
}
@end

load方法:当类加载到运行环境中时调用且仅调用一次,同时一个类只会加载一次(程序启动时,所有类加载一次,不管有没有在当前视图中用到)

http://www.hengruixuexiao.com/news/56223.html

相关文章:

  • 怎么做网站文字图片绍兴百度seo排名
  • 以小说名字做网站的小说网网站seo顾问
  • 在县城做同城网站怎么样电商大数据查询平台免费
  • 网站怎么做前后台存取seo推广公司有哪些
  • 网站开发软件系统你对网络营销的理解
  • 黄村做网站建设kol推广是什么意思
  • 郑州二七区重庆seo公司
  • 网站关键词几个最好百度权重优化软件
  • 基础建设文本网站宁波seo推广如何收费
  • 荥阳网站制作百度竞价开户
  • 网站秒杀小程序怎么做苏州seo报价
  • 网站建设主要包括两个方面网络营销有什么岗位
  • wordpress 艺人主题关键词seo公司推荐
  • 天水做网站百度上海分公司地址
  • 网站页脚怎么做建站网站
  • wordpress安全更改seo是搜索引擎营销
  • 天津做app和网站的公司南昌百度搜索排名优化
  • 怎么建设公益网站网络推广工具和方法
  • 如何增加网站会员蚂蚁bt
  • 网站初期如何推广的网络工程师培训一般多少钱
  • 制作商城公司广东seo网站优化公司
  • 广州天河区网站建设网站如何做优化推广
  • 那个网站做稻草交易5188关键词挖掘
  • 做网站是什么课天津百度seo代理
  • 网站建设流程图兰州网站开发公司
  • pathon做网站免费seo视频教程
  • 滨州做网站的电话如何创建一个网页
  • 电子商务网站建设基础项目实训报告高明搜索seo
  • 网页和网站区别是什么免费自学电商教程
  • 网站关键词怎么写邯郸今日头条最新消息