oc84--单利

简介:
复制代码
//  Tools.h

#import <Foundation/Foundation.h>

@interface Tools : NSObject<NSCopying, NSMutableCopying>
// 一般情况下创建一个单例对象都有一个与之对应的类方法,一般情况下用于创建单例对象的方法名称都以share开头, 或者以default开头
+ (instancetype)shareInstance;

@end
复制代码
复制代码
//
//  Tools.m


#import "Tools.h"

@implementation Tools

+ (instancetype)shareInstance
{
    Tools *instance = [[self alloc] init];//调用allocWithZone
    return instance;
}

static Tools *_instance = nil;
+ (instancetype)allocWithZone:(struct _NSZone *)zone  //alloc内部会调用allocWithZone
{
    // 由于所有的创建方法都会调用该方法, 所以只需要在该方法中控制当前对象只创建一次即可
    
    /*
    // 当前代码在多线程中可能会出现问题
    NSLog(@"%s", __func__);
    if (_instance == nil) {
        NSLog(@"创建了一个对象");
        _instance = [[super allocWithZone:zone] init];  //去父类创建,不能用self否则会死循环,
    }
    return _instance;
     */
    
    // 以下代码在多线程中也能保证只执行一次
    static dispatch_once_t onceToken;//long类型
    dispatch_once(&onceToken, ^{
        _instance = [[super allocWithZone:zone] init];
    });
    return _instance;
}

// copyWithZone方法用什么调用? 对象,对象已经有了,就用原来的对象。
- (id)copyWithZone:(NSZone *)zone{
//    Tools *t = [[[self class] allocWithZone:zone] init];  //调用allocWithZone,所以这里也是单利,
//    return t;
    return _instance;
}

- (id)mutableCopyWithZone:(NSZone *)zone
{
//    Tools *t = [[[self class] allocWithZone:zone] init];
//    return t;
    
    return _instance;
}










//MRC:MRC才可以写release,retain,retainCount
- (oneway void)release
{
    // 为保证整个程序过程中只有一份实例, 在这个方法中什么都不做,单利释放了就没有了。
}

- (instancetype)retain
{
    return _instance;
}

- (NSUInteger)retainCount
{
//    return 1;
    // 注意: 为了方便程序员之前沟通, 一般情况下不会在单例中返回retainCount = 1
    // 而是返回一个比较大得值
    return  MAXFLOAT;
}


@end
复制代码
复制代码
//
//  main.m
//  单例:只有一个实例,只有程序挂掉实例才释放。
//

#import <Foundation/Foundation.h>
#import "Tools.h"

int main(int argc, const char * argv[]) {
    
//ARC
    // 单例就是无论怎么创建都只能有一个实例对象
    // 如果地址相同就代表着是同一个实例对象
    Tools *t11 = [[Tools alloc] init]; //alloc内部会调用allocWithZone,这里调用allocWithZone,
    Tools *t21 = [Tools new];// [[alloc] init],  allocWithZone,,这里调用allocWithZone,
    Tools *t31 = [Tools shareInstance];//先调用shareInstance再调用allocWithZone,
    
    Tools *t41 = [t31 copy];
    Tools *t51 = [t31 mutableCopy];
    
    NSLog(@"%p, %p, %p, %p, %p", t11, t21, t31, t41, t51);//0x1005035e0, 0x1005035e0, 0x1005035e0, 0x1005035e0, 0x1005035e0
    
    
    
//MRC
    Tools *t2 = [[Tools alloc] init];
    [t2 retain];
    [t2 retain];
    [t2 retain];
    [t2 retain];
    [t2 retain];
    NSLog(@"retainCount = %lu", [t2 retainCount]);//4299163232
    NSLog(@"t2 = %p", t2);//t2 = 0x1005035e0
    [t2 release];
    
    
    Tools *t1 = [Tools shareInstance];
    NSLog(@"retainCount = %lu", [t1 retainCount]);//4299163232
    NSLog(@"t1 = %p", t1);//0x1005035e0
    [t1 release];
    
    
    return 0;
}
复制代码

 


本文转自农夫山泉别墅博客园博客,原文链接:http://www.cnblogs.com/yaowen/p/7443685.html,如需转载请自行联系原作者

相关文章
|
2月前
|
IDE Java API
Javadoc的讲解使用
本文介绍了Javadoc工具的使用方法和常用标签,通过示例代码展示了如何为Java代码添加文档注释并使用Javadoc命令生成HTML格式的API文档。
40 0
|
Oracle Java 关系型数据库
无法使用 javadoc 等命令?
谈到 Java 就离不开 JRE(Java Runtime Environment),JDK(Java Development Kit) 中包含了 JRE 和 JVM(Java Virtual Machine),所以我们一般直接安装 JDK,安装 JDK 首先肯定是去Oracle官网下载适合自己的开发版本,然后将 JDK 安装到自定义位置。
无法使用 javadoc 等命令?
|
Java API
JavaDoc
JavaDoc命令是用来生成自己API文档的,将写好的程序放在生成的文档中 参数信息 @author 作者名 @version 版本号 @since 指明需要最早使用的jdk版本 @param 参数名 @return 返回值情况 @throws 异常抛出情况 package com.wyd.base
JavaDoc
|
编译器 C语言 Swift
|
编译器 Python