0

我有包含自定义对象的 XIB,其中一个实际上是一个类集群,其-init方法总是返回相同的单例对象。

基本上:

- (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 中使用类集群吗?

4

1 回答 1

1

我通过在 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

于 2021-11-17T20:47:00.900 回答