1
0
mirror of https://github.com/danog/Telegram.git synced 2024-12-03 09:57:46 +01:00
Telegram/legacy/TelegraphKit/TGObserverProxy.m
2015-10-01 19:19:52 +03:00

128 lines
3.2 KiB
Objective-C

#import "TGObserverProxy.h"
@interface TGObserverProxyScheduledNotification : NSObject
@property (nonatomic, weak) id target;
@property (nonatomic) SEL targetSelector;
@property (nonatomic, strong) id notification;
@property (nonatomic) NSUInteger passCount;
@property (nonatomic) bool cancelled;
@end
@implementation TGObserverProxyScheduledNotification
- (instancetype)initWithTarget:(id)target targetSelector:(SEL)targetSelector notification:(id)notification passCount:(NSUInteger)passCount
{
self = [super init];
if (self != nil)
{
self.target = target;
_targetSelector = targetSelector;
_notification = notification;
_passCount = passCount;
}
return self;
}
- (void)dealloc
{
_cancelled = true;
}
- (void)execute
{
if (_cancelled)
return;
if (_passCount == 0)
{
__strong id target = self.target;
if (target != nil)
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[target performSelector:_targetSelector withObject:_notification];
#pragma clang diagnostic pop
}
}
else
{
_passCount--;
dispatch_async(dispatch_get_main_queue(), ^
{
[self execute];
});
}
}
@end
@interface TGObserverProxy ()
@property (nonatomic, weak) id target;
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) id object;
@property (nonatomic) SEL targetSelector;
@property (nonatomic) TGObserverProxyScheduledNotification *pendingNotification;
@end
@implementation TGObserverProxy
- (instancetype)initWithTarget:(id)target targetSelector:(SEL)targetSelector name:(NSString *)name
{
return [self initWithTarget:target targetSelector:targetSelector name:name object:nil];
}
- (instancetype)initWithTarget:(id)target targetSelector:(SEL)targetSelector name:(NSString *)name object:(id)object
{
self = [super init];
if (self != nil)
{
self.target = target;
self.name = name;
self.object = object;
self.targetSelector = targetSelector;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationReceived:) name:name object:object];
}
return self;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:_name object:_object];
}
- (void)notificationReceived:(NSNotification *)notification
{
if (_pendingNotification != nil)
{
_pendingNotification.cancelled = true;
_pendingNotification = nil;
}
__strong id target = self.target;
if (target != nil)
{
if (_numberOfRunLoopPassesToDelayTargetNotifications == 0)
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[target performSelector:_targetSelector withObject:notification];
#pragma clang diagnostic pop
}
else
{
_pendingNotification = [[TGObserverProxyScheduledNotification alloc] initWithTarget:self.target targetSelector:_targetSelector notification:notification passCount:_numberOfRunLoopPassesToDelayTargetNotifications];
[_pendingNotification execute];
}
}
}
@end