#objective-c #swizzling
#objective-c #перебирающий
Вопрос:
Я проверяю initWithFrame: и освобождаю MKMapView и UIScrollView для добавления и удаления прослушивателей уведомлений для мониторинга подключения к внешнему устройству, чтобы я мог подключить дополнительные средства распознавания жестов для этих представлений, например, так:
(void) swizzleMethodsForFooCategory
{
SwizzleInstanceMethods(self, @selector(initWithFrame:), @selector(foo_initWithFrame:));
SwizzleInstanceMethods(self, @selector(dealloc), @selector(foo_dealloc));
}
- (id) foo_initWithFrame: (CGRect) frame
{
NSLog(@"foo_initWithFrame: called");
self = [self foo_initWithFrame: frame];
if (self != nil)
{
NSNotificationCenter * center = [NSNotificationCenter defaultCenter];
[center addObserver: self
selector: @selector(foo_connectionDidSucceed)
name: @"PM_connectionDidSucceed"
object: nil];
[center addObserver: self
selector: @selector(foo_didDisconnect)
name: @"PM_didDisconnect"
object: nil];
}
return self;
}
- (void) foo_dealloc
{
NSLog(@"foo_dealloc called");
[[NSNotificationCenter defaultCenter] removeObserver: self name: @"PM_connectionDidSucceed" object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: self name: @"PM_didDisconnect" object: nil];
[self foo_dealloc];
}
- (void) foo_connectionDidSucceed
{
// Add gesture recognizers.
}
- (void) foo_didDisconnect
{
// Remove gesture recognizers.
}
Это отлично работает для представлений, которые я создаю в коде, но если я объявляю их в XIB, мои методы не вызываются. Я использую swizzling вместо наследования, потому что я не хочу жестко кодировать эту поддержку — я хочу иметь возможность добавлять ее для каждой цели.
Что я могу сделать, чтобы подключить эти объекты, чтобы я мог добавить свои средства распознавания жестов для всех объектов этих типов, создаю ли я их программно или в NIB?
Ответ №1:
Просмотр объектов, созданных из использования NIB -initWithCoder:
для инициализации, поэтому я бы попробовал использовать это вместо.
Комментарии:
1. Потрясающе! Большое спасибо за добавление еще одного лакомого кусочка в мою версию iOS.
2. ПРИМЕЧАНИЕ: Bavarious может быть более подходящим для материалов, которые не соответствуют
NSCoding
.3. Неуправляемые объекты nib, получающие либо
-initWithCoder:
, либо-init
описано в Руководстве по программированию ресурсов .
Ответ №2:
В iOS каждый объект, загруженный из файла nib, получает либо -initWithCoder:
(если соответствующий класс соответствует NSCoding
протоколу), либо -init
(если соответствующий класс не соответствует NSCoding
протоколу) при удалении из файла nib. Это отличается от Mac OS X, где пользовательские представления получают -initWithFrame:
, а другие объекты получают либо -initWithCoder:
, либо -init
.
Поскольку ваши классы наследуются от UIView
, что соответствует NSCoding
протоколу, вам нужно swizzle -initWithCoder:
.