Swizzling initWithFrame:不适用于 NIB 中的对象
我正在 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
从 NIB 实例化的视图对象使用
-initWithCoder:
进行初始化,因此我会尝试调整它。View objects instantiated from a NIB use
-initWithCoder:
to initialize, so I'd try swizzling that instead.在 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 theNSCoding
protocol) or-init
(if the corresponding class doesn’t conform to theNSCoding
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 theNSCoding
protocol, you need to swizzle-initWithCoder:
.