dispatch_once的使用

在学习dispatch_once之前,需要学习的就是单例设计模式了。作为23种经典设计模式之一,虽然简单,但是非常的实用。
那么什么是单例设计模式呢? 以下是百度百科的解释,:
单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。
链接为:http://baike.baidu.com/view/1859857.htm?fr=aladdin
维基百科的解释为:
单例模式,也叫 单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。
链接为:http://zh.wikipedia.org/wiki/单例模式

其核心的思想:单例类有且只有一个实例。

在Apple当中,可以通过dispath_once来实现单例模式。以下是引入apple的说明:
可以看到  
    1)代码仅仅会运行一次:Executes a block object once and only once for the lifetime of an application.
    2)多线程安全的:If called simultaneously from multiple threads, this function waits synchronously until the block has completed.
    3)在IOS4.0之后引入的: Available in iOS 4.0 and later.

同时需要注意的是:
    1)The predicate must point to a variable stored in global or static scope.

dispatch_once


Executes a block object once and only once for the lifetime of an application.

   void dispatch_once(
   dispatch_once_t *predicate,
   dispatch_block_t block);
 
 
Parameters
predicate

A pointer to a dispatch_once_t structure that is used to test whether the block has completed or not.()

block

The block object to execute once.

Discussion

This function is useful for initialization of global data (singletons) in an application. Always call this function before using or testing any variables that are initialized by the block.

If called simultaneously from multiple threads, this function waits synchronously until the block has completed.

The predicate must point to a variable stored in global or static scope. The result of using a predicate with automatic or dynamic storage (including Objective-C instance variables) is undefined.
Availability
  • Available in iOS 4.0 and later.
Declared In
dispatch/once.h


以下为具体创建的实例:
  + (ModalManage *)SharedModal

{

    static dispatch_once_t once;

    static id instance = nil;

    dispatch_once(&once, ^{

        instance = [[self alloc]init];

    });

    return instance;

}

可以看到,仅仅几行代码,就实现了一个线程安全的单例实例。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LLRuntime 是 iOS 开发中常用的一个运行时库,可以在运行时动态地获取和修改对象的属性、方法等信息,常用于实现方法交换、动态添加方法等功能。下面是 LLRuntime 的使用方法: 1. 导入 LLRuntime 库 在 Xcode 中,可以使用 CocoaPods 导入 LLRuntime 库,也可以手动导入。手动导入的方式是: 将 LLRuntime 文件夹拖入项目中,勾选“Copy items if needed”。 在 Build Phases 中的 Link Binary With Libraries 中添加 libLLRuntime.a。 2. 使用 LLRuntime 2.1 获取类的信息 获取类的信息可以使用以下方法: ```objc Class cls = [NSObject class]; // 获取类名 const char *name = class_getName(cls); NSLog(@"class name: %s", name); // 获取父类 Class superCls = class_getSuperclass(cls); NSLog(@"super class name: %s", class_getName(superCls)); // 获取实例变量 unsigned int ivarCount; Ivar *ivarList = class_copyIvarList(cls, &ivarCount); for (unsigned int i = 0; i < ivarCount; i++) { Ivar ivar = ivarList[i]; const char *ivarName = ivar_getName(ivar); const char *ivarType = ivar_getTypeEncoding(ivar); NSLog(@"ivar name: %s, type: %s", ivarName, ivarType); } free(ivarList); // 获取属性 unsigned int propertyCount; objc_property_t *propertyList = class_copyPropertyList(cls, &propertyCount); for (unsigned int i = 0; i < propertyCount; i++) { objc_property_t property = propertyList[i]; const char *propertyName = property_getName(property); const char *propertyAttributes = property_getAttributes(property); NSLog(@"property name: %s, attributes: %s", propertyName, propertyAttributes); } free(propertyList); // 获取方法 unsigned int methodCount; Method *methodList = class_copyMethodList(cls, &methodCount); for (unsigned int i = 0; i < methodCount; i++) { Method method = methodList[i]; SEL methodName = method_getName(method); const char *methodType = method_getTypeEncoding(method); NSLog(@"method name: %@, type: %s", NSStringFromSelector(methodName), methodType); } free(methodList); ``` 2.2 方法交换 方法交换可以使用以下方法: ```objc @implementation NSObject (LLRuntime) + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Class cls = [self class]; SEL originalSEL = @selector(description); SEL swizzledSEL = @selector(ll_description); Method originalMethod = class_getInstanceMethod(cls, originalSEL); Method swizzledMethod = class_getInstanceMethod(cls, swizzledSEL); BOOL didAddMethod = class_addMethod(cls, originalSEL, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod)); if (didAddMethod) { class_replaceMethod(cls, swizzledSEL, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); } else { method_exchangeImplementations(originalMethod, swizzledMethod); } }); } - (NSString *)ll_description { NSString *description = [self ll_description]; return [NSString stringWithFormat:@"<%@: %p, desc: %@>", NSStringFromClass([self class]), self, description]; } @end ``` 2.3 动态添加方法 动态添加方法可以使用以下方法: ```objc @implementation NSObject (LLRuntime) - (void)ll_setName:(NSString *)name { objc_setAssociatedObject(self, @selector(ll_name), name, OBJC_ASSOCIATION_COPY_NONATOMIC); } - (NSString *)ll_name { return objc_getAssociatedObject(self, _cmd); } + (BOOL)resolveInstanceMethod:(SEL)sel { if (sel == @selector(ll_name)) { class_addMethod([self class], sel, (IMP)ll_name, "@@:"); return YES; } return [super resolveInstanceMethod:sel]; } @end ``` 以上就是 LLRuntime 的使用方法,可以根据实际需求选择使用

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值