2

我在我的项目中使用ARC

我有 1 节课是这样的:

@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

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

但是当我再次调用它时......

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

我在块中做了很多断点,dispatch_once没有调用断点。


所以我的问题是:

  1. 用方法写static id object;和用方法写,有区别吗?

  2. 如何释放所有实例对象以便我仍然可以再次调用它们?(我想使用 ARC,我可以在没有 ARC 的情况下做到这一点)

4

2 回答 2

3

我认为你应该oncePredicate在发布时设置为 0_shareInstance

@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

这个对我有用!

于 2014-03-11T11:17:54.870 回答
2

要按顺序回答您的问题...

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

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

于 2013-10-09T11:52:45.233 回答