2

我在 MKMapView 和 UIScrollView 上调配 initWithFrame: 和 dealloc 以添加和删除通知侦听器以监视与外部设备的连接,这样我就可以为这些视图连接额外的手势识别器,如下所示:

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

2 回答 2

4

从 NIB 实例化的视图对象-initWithCoder:用于初始化,所以我会尝试调整它。

于 2011-05-12T01:30:07.327 回答
2

在 iOS 中,从 nib 文件加载的每个对象在从 nib 文件解组时接收-initWithCoder:(如果相应的类符合NSCoding协议)或-init(如果相应的类不符合NSCoding协议)。这是与 Mac OS X 不同的行为,在 Mac OS X 中,自定义视图接收-initWithFrame:而其他对象接收-initWithCoder:-init

由于您的类继承自UIView符合NSCoding协议的 ,因此您需要 swizzle -initWithCoder:

于 2011-05-12T01:33:11.380 回答