macOS 12.0.1 (Monterey) XIB 加载失败;抛出异常 "This coder is expecting the replaced object ... to be returned from NSClassSwapper"
macOS 12.0.1 (Monterey) XIB fails to load; throwing exception "This coder is expecting the replaced object ... to be returned from NSClassSwapper"
我有包含自定义对象的 XIB,其中之一实际上是一个 class 集群,其 -init
方法总是 returns 相同的单例对象。
基本上:
- (instancetype)init
{
self = [super init];
if (HelpLinkHelperSingleton==nil)
{
// This is the first instance of DDHelpLink: make it the immortal singleton
HelpLinkHelperSingleton = self;
}
else
{
// Not the first DDHelpLink object to be created: discard this instance
// and return a reference to the shared singleton
self = HelpLinkHelperSingleton;
}
return self;
}
从 macOS 12.0.1 开始,加载 XIB 会抛出此异常:
This coder is expecting the replaced object 0x600002a4f680 to be returned from NSClassSwapper.initWithCoder instead of <DDHelpLink: 0x600002a487a0>
我尝试实施 <NSSecureCoding>
并做同样的事情,但这也不起作用。
还有办法在 NIB 中使用 class 集群吗?
我通过使用 XIB 中的代理对象将消息转发给单例解决了这个问题。
@interface HelpLinkHelperProxy : NSObject
@end
@implementation HelpLinkHelperProxy
{
HelpLinkHelper* _singleton;
}
- (void) forwardInvocation:(NSInvocation*)invocation
{
if (_singleton == nil)
{
_singleton = [HelpLinkHelper new];
}
if ([_singleton respondsToSelector:[invocation selector]])
{
[invocation invokeWithTarget:_singleton];
}
else
{
[super forwardInvocation:invocation];
}
}
@end
如果我们从 NSProxy
而不是 NSObject
继承子类,解决方案将如下所示:
@interface HelpLinkHelperProxy : NSProxy
@end
@implementation HelpLinkHelperProxy
{
HelpLinkHelper* _singleton;
}
- (instancetype) init
{
_singleton = [HelpLinkHelper new];
return self;
}
- (NSMethodSignature*) methodSignatureForSelector:(SEL)sel
{
return [_singleton methodSignatureForSelector:sel];
}
- (void) forwardInvocation:(NSInvocation*)invocation
{
if ([_singleton respondsToSelector:[invocation selector]])
{
[invocation invokeWithTarget:_singleton];
}
else
{
[super forwardInvocation:invocation];
}
}
+ (BOOL) respondsToSelector:(SEL)aSelector
{
return [HelpLinkHelper respondsToSelector:aSelector];
}
@end
我有包含自定义对象的 XIB,其中之一实际上是一个 class 集群,其 -init
方法总是 returns 相同的单例对象。
基本上:
- (instancetype)init
{
self = [super init];
if (HelpLinkHelperSingleton==nil)
{
// This is the first instance of DDHelpLink: make it the immortal singleton
HelpLinkHelperSingleton = self;
}
else
{
// Not the first DDHelpLink object to be created: discard this instance
// and return a reference to the shared singleton
self = HelpLinkHelperSingleton;
}
return self;
}
从 macOS 12.0.1 开始,加载 XIB 会抛出此异常:
This coder is expecting the replaced object 0x600002a4f680 to be returned from NSClassSwapper.initWithCoder instead of <DDHelpLink: 0x600002a487a0>
我尝试实施 <NSSecureCoding>
并做同样的事情,但这也不起作用。
还有办法在 NIB 中使用 class 集群吗?
我通过使用 XIB 中的代理对象将消息转发给单例解决了这个问题。
@interface HelpLinkHelperProxy : NSObject
@end
@implementation HelpLinkHelperProxy
{
HelpLinkHelper* _singleton;
}
- (void) forwardInvocation:(NSInvocation*)invocation
{
if (_singleton == nil)
{
_singleton = [HelpLinkHelper new];
}
if ([_singleton respondsToSelector:[invocation selector]])
{
[invocation invokeWithTarget:_singleton];
}
else
{
[super forwardInvocation:invocation];
}
}
@end
如果我们从 NSProxy
而不是 NSObject
继承子类,解决方案将如下所示:
@interface HelpLinkHelperProxy : NSProxy
@end
@implementation HelpLinkHelperProxy
{
HelpLinkHelper* _singleton;
}
- (instancetype) init
{
_singleton = [HelpLinkHelper new];
return self;
}
- (NSMethodSignature*) methodSignatureForSelector:(SEL)sel
{
return [_singleton methodSignatureForSelector:sel];
}
- (void) forwardInvocation:(NSInvocation*)invocation
{
if ([_singleton respondsToSelector:[invocation selector]])
{
[invocation invokeWithTarget:_singleton];
}
else
{
[super forwardInvocation:invocation];
}
}
+ (BOOL) respondsToSelector:(SEL)aSelector
{
return [HelpLinkHelper respondsToSelector:aSelector];
}
@end