2011-05-12 4 views
2

Я swizzling initWithFrame: и dealloc на MKMapView и UIScrollView для добавления и удаления прослушивателей уведомлений для мониторинга подключения к внешнему устройству, чтобы я мог подключить дополнительные распознаватели жестов для этих просмотров, как так:Swizzling initWithFrame: не работает для объектов в NIB

+ (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?

ответ

4

Просмотреть объекты, созданные из NIB, использовать -initWithCoder: для инициализации, поэтому вместо этого я попробую swizzling.

+0

Awesome! Большое спасибо за добавление еще одного лакомого кусочка в iOS fu. –

+0

NB: Bavarious может быть более прав для вещей, которые не соответствуют «NSCoding». – Wevah

+1

Unsmarshalled nib объекты, получающие «-initWithCoder:' или '-init', описаны в [Руководстве по программированию ресурсов] (http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs /CocoaNibs.html). –

2

В прошивке, каждый объект загружается из файла кончика пера получает либо -initWithCoder: (если соответствующий класс соответствует NSCoding протоколу) или -init (если соответствующий класс не соответствует протоколу NSCoding) при unmarshalled из файла СИБА , Это другое поведение от Mac OS X, где пользовательские представления получают -initWithFrame:, а другие объекты получают либо -initWithCoder:, либо -init.

Так как ваши классы наследуются от UIView, что соответствует протоколу NSCoding, вам необходимо выполнить swizzle -initWithCoder:.

+0

Отлично, спасибо большое. –

Смежные вопросы