Получить все экземпляры класса в target c?

У меня есть UIView со многими экземплярами, и каждый из них имеет UIRecognizer.

Когда один из них нажат, я хочу удалить все распознаватели остальных.

Я хочу, чтобы он получил все экземпляры класса и удалил их распознавание.

Я знаю, что в ManagedObjects есть [Entity allObjects];

Как я могу создать свой метод класса «все объекты»?


person shannoga    schedule 15.12.2011    source источник


Ответы (4)


У меня есть две идеи:

1/ Создайте массив классов со всеми экземплярами static NSArray* instances;, зарегистрируйте их при инициализации, отмените регистрацию при освобождении. В массиве должны быть только слабые ссылки, иначе они никогда не будут освобождены.

2/NS-уведомление. Все экземпляры могут ожидать уведомления, и если вы нажмете, вы отправите уведомление.

person Sulthan    schedule 15.12.2011
comment
Спасибо, это действительно полезно - person shannoga; 13.01.2012

Во-первых, я бы сказал, что все, что вы пытаетесь выполнить, может быть лучше выполнено с помощью NSNotificationCenter, тем не менее, если вам все еще нужно это сделать, следующее будет работать и будет соответствовать ARC.

В вашем .h добавьте это:

+(NSArray *)allInstances;

Затем добавьте это в конец .m вашего класса:

-(id)init {
    //Note, I suppose you may need to account for exotic init types if you are creating instances of your class in non-traditional ways. I see in the docs that initWithType: exists for example, not sure what storyboard calls
    self = [super init];
    [[self class] trackInstance:self];
    return self;
}
-(void)dealloc {
    [[self class] untrackInstance:self];
}

static NSMutableArray *allWeakInstances;
+(void)trackInstance:(id)instance {
    if (!allWeakInstances) {
        allWeakInstances = [NSMutableArray new];
    }
    NSValue *weakInstance = [NSValue valueWithNonretainedObject:instance];
    [allWeakInstances addObject:weakInstance];
}
+(void)untrackInstance:(id)instance {
    NSValue *weakInstance = [NSValue valueWithNonretainedObject:instance];
    [allWeakInstances removeObject:weakInstance];
}
+(NSArray *)allInstances {
    NSMutableArray *allInstances = [NSMutableArray new];
    for (NSValue *weakInstance in allWeakInstances) {
        [allInstances addObject:[weakInstance nonretainedObjectValue]];
    }
    return allInstances.copy;
}

Затем, когда вам понадобятся все экземпляры класса, просто вызовите [Class allInstances];

person Albert Renshaw    schedule 19.04.2020

Если вам просто нужно найти все экземпляры для целей отладки, вы можете использовать инструмент Allocations и изменить Recorded Types только на свой класс. Это даст вам прекрасный список всех ваших объектов. Затем вы можете взаимодействовать с ними, используя lldb, используя их адрес.

person Maciej Swic    schedule 26.11.2015

Если все они являются подвидами одного и того же представления, вы можете перебрать parentView.subviews и найти их таким образом. Что-то вроде этого:

for (UIView *v in parentView.subviews) {
    if ([v isKindOfClass:[MyViewClass class]]) {
        // remove recognizer here
    }
}

Другим, более эффективным вариантом было бы иметь флаг в вашем контроллере представления, который вы устанавливаете, когда запускается первый распознаватель, и используете его для короткого замыкания любых будущих вызовов обработчика распознавателя. Что-то вроде этого:

@property (nonatomic) BOOL shouldRespondToEvent;
@synthesize shouldRespondToEvent=_shouldRespondToEvent;

- (void)viewDidLoad {
    [super viewDidLoad];
    self.shouldRespondToEvent = YES;
    // other viewDidLoad stuff here
}

- (void)gestureHandler:(UIGestureRecognizer*)recognizer {
    if (!self.shouldRespondToEvent)
        return;
    self.shouldRespondToEvent = NO;
    // rest of handler code here
}
person Simon Whitaker    schedule 15.12.2011