Swizzling initWithFrame:不适用于 NIB 中的对象

发布于 2024-11-06 14:31:38 字数 1575 浏览 7 评论 0原文

我正在 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 中声明它们,我的方法就不会被调用。我使用调配而不是继承,因为我不想硬编码此支持 - 我希望能够在每个目标的基础上添加它。

我可以做什么来挂钩这些对象,以便为这些类型的所有对象添加手势识别器,无论是通过编程方式还是在 NIB 中创建它们?

I'm swizzling initWithFrame: and dealloc on MKMapView and UIScrollView to add and remove notification listeners to monitor connection to an external device so I can hook up additional gesture recognizers for these views, like so:

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

This works great for views that I create in code, but if I declare them in an XIB my methods don't get called. I'm using swizzling instead of inheritance because I don't want to hard-code this support - I want to be able to add it on a per-target basis.

What can I do to hook these objects so I can add my gesture recognizers for all objects of these types whether I create them programmatically or in a NIB?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

绮烟 2024-11-13 14:31:38

从 NIB 实例化的视图对象使用 -initWithCoder: 进行初始化,因此我会尝试调整它。

View objects instantiated from a NIB use -initWithCoder: to initialize, so I'd try swizzling that instead.

情绪操控生活 2024-11-13 14:31:38

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

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

In iOS, every object loaded from a nib file receive either -initWithCoder: (if the corresponding class conforms to the NSCoding protocol) or -init (if the corresponding class doesn’t conform to the NSCoding protocol) when unmarshalled from the nib file. This is a different behaviour from Mac OS X, where custom views receive -initWithFrame: and other objects receive either -initWithCoder: or -init.

Since your classes inherit from UIView, which conforms to the NSCoding protocol, you need to swizzle -initWithCoder:.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文