Single-instance mode in iOS: MRC and ARC+GCD implementations

Source: Internet
Author: User

The implementation of the Singleton pattern in iOS is generally divided into two types: MRC and ARC+GCD

1.MRC (non-ARC)

Non-Arc single-instance implementations:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <span style="font-family: 仿宋; font-size: 15px;">#import <Foundation/Foundation.h> @interface NoARCSingleton:NSObject <span>//这个属性在后面调试有用处,而且也不要苦恼为什么是retain?不应该是copy么?请继续看下去,后面自然明白了<br></span>@property (nonatomic,retain) NSString *tempProperty; +(NoARCSingleton *)sharedInstance; @end @implementation NoARCSingleton static NoARCSingleton  *sharedInstance  = nil; //获取一个单例对象 + (BVNonARCSingleton *)sharedInstance {<br>//--------------------------------------------------<br>  if (sharedInstance == nil) {         sharedInstance = [[super allocWithZone:NULL] init];     }    return sharedInstance;<br>//-------------------------------------------------- } //当第一次使用这个单例的时候,会调用这个init方法。 -(id)init {    self = [super init];   if(self){    //通常在这里做一些相关的初始化任务   return self;     }      } //这个delloc方法永远都不会被调用,因为在程序的生命周期内,该单例都必须存在,该方法可以不用实现 -(void)delloc {   [super dealloc]; }//通过返回当前的单例对象的方式来防止实例化新的对象 + (id)allocWithZone:(NSZone*)zone {<br>  //线程相关的操作安全有</span>sharedInstance处理
?
1 2 3 4 5 6 7 <span style="font-family: 仿宋; font-size: 15px;">return [[self sharedInstance] retain]; } <br>Similarly, you do not want to generate multiple copies of the singleton, you must override <br>-(ID) Copywithzone: (Nszone *) zone {return self;} <br>// None of the operations in this method need a reference count (retain counter) <br>-(ID) retain {return self;} <br>//Replace the reference counter, which will never release this singleton <br>-(Nsuinteger) Retaincount {return nsuintegermax;} <br>// The method is empty-do not want the user to release the object. <br>-(OneWay void) release{}<br>//In addition to returning the single exception, do nothing. <br>-(ID) autorelease {return self;} <br> @end <br>//@synchronized's role is to create a mutex, Ensure that no other threads are modifying the Self object at this time. This is a lock token for objective-c, which prevents the self object from being accessed by other threads at the same time, and acts as a thread protection. Generally used in the case of common variables, such as singleton mode or the static variable of an operation class. <br>//Non-ARC implementation of the Singleton method is thread insecure, if there are multiple threads calling the <span>sharedinstance method at the same time to get an instance, <span> Sharedinstance takes 1-2s of time, the <span>nonarcsingleton init method may be called multiple times, that is, multiple threads may not be a singleton, and the way to solve this thread is unsafe by using <a href= "https://developer.apple.com/library/mac/#documentation/cocoa/conceptual/multithreading/threadsafety /threadsafety.html "target=" _blank "><span class=" Edui-filter-underline "> @synchronized &LT;/span></a><span> to create a mutex. <br>//<span> of course, this method does not guarantee that the invocation of all methods in this singleton is thread-safe </span><br></span></span></span ></span>//so the code between the lines above should be replaced with the following code @synchronized (self)</span> {      if(sharedInstance == nil)     {        sharedInstance = [[super allocWithZone:NULL] init]; }<br>#param mark <span style="font-family: 仿宋; font-size: 15px;">-提醒:在iOS中,一般不建议使用非ARC来实现单例模式。更好的方法是使用ARC+GCD来实现。</span>

  How arc is implemented

?
1 2 3 4 5 6 7 <span style="font-family: 仿宋; font-size: 15px;">#import "ARCSingleton.h" @interface ARCSingleton : NSObject<br>//调试之用和上面的代码作用类似的,这里为什么用weak呢?请继续看下去~<br><span>@property  ( nonatomic, weak) NSString  *tempProperty;</span> + (ARCSingleton *)sharedInstance; @end @implementation ARCSingleton + (ARCSingleton *) sharedInstance {<br><span style="line-height: 1.5;">      staticARCSingleton *sharedInstance = nil ;</span></span>
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <span style="font-family: 仿宋; font-size: 15px;">     staticdispatch_once_t onceToken = 0;  // 锁      dispatch_once (&onceToken, ^ {     // 最多调用一次        sharedInstance = [[self alloc] init];     });     returnsharedInstance; } //当第一次使用这个单例时,会调用这个init方法 -(id)init {     self = [super init];     if(self){        //初始化单例     }       return self;   } @end <br>//<span>在上面的代码中,调用</span><span class="edui-filter-underline"><a href="http://developer.apple.com/library/ios/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html" target="_blank">Grand Central Dispatch <br>(GCD)</a></span><span>中的</span><span class="edui-filter-underline"><a href="https://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html#//apple_ref/c/func/dispatch_once" target="_blank">dispatch_once</a></span><span>方法就可以确保ARCSingleton只被实例化一次。并且该方法是线程安全的,我们不用担心在不同的线程中,会获得不同的实例。(当然,该方法同样不能保证该单例中所有方法的调用都是线程安全的)。</span><br> </span>

  Of course, in the arc, without GCD can also be thread-safe, with the previous non-arc code using @synchronized, the following code:

?
1 2 3 4 5 6 7 8 9 <span style="font-family: 仿宋; font-size: 15px;"> // 不使用GCD,通过@synchronized @synchronized (self) {    if(sharedInstance == nil)     {         sharedInstance = [[self alloc] init];     } } </span>

  To simplify the use of ARC+GCD to create a singleton, you can use the following macro

?
1 2 3 4 5 6 7 8 9 10 11 #define DEFINE_SHARED_INSTANCE_USING_BLOCK(block) \static dispatch_once_t onceToken = 0; \  static id sharedInstance = nil; \dispatch_once(&onceToken, ^{ \sharedInstance = block(); \}); \return sharedInstance; \<br><span style="font-family: 仿宋; font-size: 15px;">//如果对于macro有问题的话强烈建议去脑补下猫神的文章http://onevcat.com/2014/01/black-magic-in-macro/<br>//另外猫神的很多文章都是很深入的建议有时间多去细细品味</span>

 After the macro has been written, then easy!

Instantiation method Implementation:

?
1 2 3 4 5 6 + (BVARCSingleton *) sharedInstance {    DEFINE_SHARED_INSTANCE_USING_BLOCK(^{        return [[self alloc] init];     });}<br>//Done

  Single use: The use of a single example is very simple, anywhere in the code, such as the following can be used:

to add a header file in BVAPPDELEGATE.M:
#import "NonARCSingleton.h"
#import "ARCSingleton.h"

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {       [NonARCSingleton sharedInstance].tempProperty = @"非ARC单例的实现";       NSLog(@"%@", [BVNonARCSingleton sharedInstance].tempProperty);      [ARCSingleton sharedInstance].tempProperty = @"ARC单例的实现";        NSLog(@"%@", [ARCSingleton sharedInstance].tempProperty);        return YES; }

   Additional Dry Goods

  __weak,__strong


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.