获取 Objective C 中某个类的所有实例?

发布于 2024-12-21 06:50:37 字数 201 浏览 0 评论 0原文

我有一个 UIView,它有很多实例,每个实例都有一个 UIRecognizer。

当其中一个被点击时,我想删除其他人的所有识别器。

我希望它获取该类的所有实例并删除它们的识别。

我知道 ManagedObjects 有 [Entity allObjects];

我如何创建我的“所有对象”类方法?

I have a UIView that has many instances and each one of them has a UIRecognizer.

When on of them is tapped I want to remove all the recognizers of the others.

What I want it to get all the instances of the class and remove their recognizes.

I know ManagedObjects has [Entity allObjects];

How can I create my "all objects" class method ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

思慕 2024-12-28 06:50:37

我有两个想法:

1/创建一个包含所有实例的类数组static NSArray*实例;,在初始化时注册它们,在释放时取消注册。该数组应该只有弱引用,否则它们将永远不会被释放。

2/ NS通知。所有实例都可以等待通知,如果您点击,则会发送通知。

I have two ideas:

1/ Create a class array with all the instances static NSArray* instances;, register them when initializing, unregister when deallocating. The array should have only weak references, otherwise they will never be deallocated.

2/ NSNotification. All instances can wait for a notification and if you tap, you send the notification.

请你别敷衍 2024-12-28 06:50:37

首先,我想说无论你想要完成什么,都可以使用 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];

First I'd say whatever you're trying to accomplish can likely be better accomplished with NSNotificationCenter, that said, if you still need to do this, the following will work and will be ARC compliant.

In your .h add this:

+(NSArray *)allInstances;

Then, add this to the bottom of your class's .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;
}

Then when you need all instances of the class, just call [Class allInstances];

累赘 2024-12-28 06:50:37

如果您只需要查找所有实例以进行调试,则可以使用分配工具并将记录类型更改为仅您的类。这将为您提供所有对象的漂亮列表。然后,您可以使用 lldb 通过他们的地址与他们进行交互。

If you just need to find all instances for debugging purposes, you can use the Allocations instrument and change the Recorded Types to only your class. This will give you a dandy list of all your objects. You can then interact with them using lldb by using their address.

谢绝鈎搭 2024-12-28 06:50:37

如果它们都是同一视图的子视图,您可以迭代 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
}

If they're all subviews of the same view, you could iterate over parentView.subviews and find them that way. Something like this:

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

Another, more efficient, option would be to have a flag in your view controller that you set when the first recognizer is triggered and use to short-circuit any future recognizer handler calls. Something like this:

@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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文