#objective-c
#objective-c
Вопрос:
Я пытаюсь разобраться, как работает делегирование обратного вызова события. До сих пор я написал следующий код, который, кстати, работает просто отлично:
Bridge.h
@protocol BridgeDelegate <NSObject>
- (void) bridgeLock;
@end
@interface Bridge : NSObject
(instancetype) sharedInstance;
@property (weak, nonatomic) id<BridgeDelegate> bridgeDelegate;
- (void) wipe;
@end
Bridge.m
@implementation Bridge
(instancetype) sharedInstance {
static dispatch_once_t pred;
static id shared = nil;
dispatch_once(amp;pred, ^{
shared = [[super alloc] initUniqueInstance];
});
return shared;
}
-(instancetype) initUniqueInstance {
return [super init];
}
- (void) wipe
{
NSLog(@"lock in bridge called");
if(self.bridgeDelegate)
{
[self.bridgeDelegate bridgeLock];
}
}
@end
Plugin.h
@interface Plugin : NSObject<BridgeDelegate>
@property (strong, nonatomic) Bridge *bridge;
- (void) pluginInitialize;
@end
Plugin.m
@implementation Plugin
- (void) pluginInitialize
{
self.bridge = [Bridge sharedInstance];
self.bridge.bridgeDelegate = self;
}
- (void)bridgeLock
{
NSLog(@"lock in plugin called");
}
@end
Когда я вызываю следующий код в applicationDidBecomeActive
Bridge* bridge = [Bridge sharedInstance];
Plugin* plugin = [[Plugin alloc] init];
[plugin pluginInitialize];
[bridge wipe];
Я получаю следующий ожидаемый результат:
lock in bridge called
lock in plugin called
Теперь мои вопросы:
-
Как именно работает делегат? В смысле, плагин только реализует функцию
bridgewipe()
, верно? Почему и как bridgeLock вызывается в первую очередь? -
Имеет ли это какое-либо отношение к тому факту, что Bridge является одноэлементным. Если бы я сделал Bridge не одноэлементным классом, будет ли конечный результат таким же.
Ответ №1:
1. Как именно работает делегирование? В смысле, плагин реализует только функцию bridgewipe(), верно? Почему и как bridgeLock вызывается в первую очередь?
В приведенном выше вставленном коде «Plugin.m» реализует - (void)bridgeLock
- Имеет ли это какое-либо отношение к тому факту, что Bridge является одноэлементным. Если бы я сделал Bridge не одноэлементным классом, будет ли конечный результат таким же.
НЕТ
Ответ №2:
Bridge* bridge = [Bridge sharedInstance];
этот мост мы называем его B1;
B1 — это экземпляр, созданный методом "sharedInstance"
;
затем вы вызываете следующий код :
Plugin* plugin = [[Plugin alloc] init];
[plugin pluginInitialize];
pluginInitialize
метод, которым ваш код является
{
self.bridge = [Bridge sharedInstance];
self.bridge.bridgeDelegate = self;
}
при выполнении кода self.bridge
также создается экземпляр методом "sharedInstance";
, который равен B1 с адресом, а также создает B1 delegate == self;
поэтому, когда вы вызываете [bridge wipe]
;
- Это приведет
nslog @"lock in bridge called"
; - Поскольку self.bridgeDelegate не равен нулю, поэтому delegate вызовет
bridgeLock
метод; - Затем
nslog @"lock in plugin called"
.
Что касается вашего второго вопроса, когда вы делаете Bridge не одноэлементным классом, я думаю, результат будет другим.
Комментарии:
1. Привет @ezatu, спасибо, что нашли время написать это. Я поиграл со своим кодом, и, как упоминал харисзаман в своем ответе, не имеет значения, является ли класс одноэлементным или нет. По этой причине я принял его ответ. Еще раз спасибо.
Ответ №3:
@hariszaman, объяснение правильное, но я хотел бы подробнее остановиться на этом, чтобы это могло помочь кому-то в будущем. В основном это то, что происходит.
- Я создаю экземпляр класса Bridge. Этот экземпляр в памяти имеет ссылочную переменную типа BridgeDelegate .
- Когда я создаю экземпляр плагина, переменная BridgeDelegate начинает указывать на экземпляр класса плагина.
- Теперь, когда вызывается lock, он вызывает метод bridgelock класса, на который указывает указатель BridgeDelegate, который в данном случае является плагином.
-
Не имеет значения, является ли класс моста не одноэлементным, потому что следующая строка в pluginInitialize:
{ self.bridge = [Bridge sharedInstance]; self.bridge.bridgeDelegate = self; }
будет изменено на :
{
self.bridge = [[Bridge alloc] init];
self.bridge.bridgeDelegate = self;
}
и шаги 1,2 и 3 будут повторяться таким же образом.