如何释放通过dispatch_once创建的实例对象

时间:2013-10-09 11:16:17

标签: ios objective-c instance instance-variables dispatch

我使用 ARC 作为我的项目

我有一个这样的课程:

@implementation MyObject

+ (instancetype)shareInstance {
    static id _shareInstance = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        _shareInstance = [[self alloc] init];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(freeInstance)
                                                     name:kLC_Notification_FreeAllInstance object:nil];
    });
    return _shareInstance;
}
+ (void)freeInstance {
    /*I want to release object "_shareInstance" but how??? */
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end

但我无法释放我的实例对象,所以我必须更改:

移动代码行 static id _shareInstance = nil;退出+shareInstance

@implementation MyObject
static id _shareInstance = nil;
+ (instancetype)shareInstance {
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        _shareInstance = [[self alloc] init];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(freeInstance)
                                                     name:kLC_Notification_FreeAllInstance object:nil];
    });
    return _shareInstance;
}
+ (void)freeInstance {
    _shareInstance = nil;
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end

当我使用name:kLC_Notification_FreeAllInstance推送通知时,所有实例对象都被释放(所有dealloc方法都被调用)。 没关系

但是当我再次打电话时......

下次调用时未初始化所有实例。之后所有实例对象都将为零

我在dispatch_once的块中创建了许多断点,并且没有调用断点。


所以我的问题是:

  1. 在方法中写static id object;并写出方法,它们有什么不同吗?

  2. 如何释放所有实例对象,以便我仍然可以再次调用它们?(我想使用ARC,我可以不使用ARC)

2 个答案:

答案 0 :(得分:3)

我认为你应该在发布oncePredicate

时将_shareInstance设置为0
@implementation MyObject
static id _shareInstance = nil;
static dispatch_once_t oncePredicate;
+ (instancetype)shareInstance {
    dispatch_once(&oncePredicate, ^{
        _shareInstance = [[self alloc] init];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(freeInstance)
                                                     name:kLC_Notification_FreeAllInstance object:nil];
    });
    return _shareInstance;
}
+ (void)freeInstance {
    _shareInstance = nil;
    oncePredicate = 0;
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end

对我有用!

答案 1 :(得分:2)

按顺序回答你的问题......

  1. 在方法内部和外部编写静态变量之间的区别在于范围,即在方法内部编写静态时,只能从该方法中访问它。

  2. 这有点棘手,因为名称dispatch_once只在块中运行一次代码,但我相信它依赖于令牌/谓词来同步它,所以将它移到shareInstance和设置为0应该意味着dispatch_once下次运行块(一次)