Domanda

I use ARC for my project

I have 1 class like this:

@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

But I can not release my instance object, so I have to change:

(move code line static id _shareInstance = nil; out of +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

When I push notifcation with name:kLC_Notification_FreeAllInstance, all instance objects are release (all dealloc methods are both called). It's OK

BUT when I call it again....

all instances are not initialized on next call. And all instance objects will be nil after that

I made many breakpoint in block of dispatch_once and no breakpoint is called.


So my questions are:

  1. Writing static id object;in a method and writing out of method, are they different?

  2. How can I free all instance objects so I can still call them again?(I want to use ARC, I can do it without ARC)

È stato utile?

Soluzione 2

To answer your question in order...

  1. The difference between writing the static variable inside and outside the method is scope, i.e. when writing the static inside the method it is only accessible from within that method.

  2. This is a bit more tricky, as suggested by the name dispatch_once only runs the code in the block once, but I believe that it relies on the token/predicate to synchronize this, so moving this outside the shareInstance and setting to 0 should mean the the dispatch_once runs the block (once) the next time around

Altri suggerimenti

I think you should set oncePredicate to 0 when releasing _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

It works for me!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top