Objective-C单例只响应类方法

Rob*_*Rob 0 iphone singleton objective-c ios

我有一个单例类,实例化如下:

#import "FavoritesManager.h"

static FavoritesManager *sharedFavoritesManager = nil;

@implementation FavoritesManager

+ (id)sharedManager {
    @synchronized(self) {
        if (sharedFavoritesManager == nil) {
            sharedFavoritesManager = [[self alloc] init];
        }
    }

    return self;
}
Run Code Online (Sandbox Code Playgroud)

这会返回一个对象,但由于某种原因它只会响应类方法.如果我调用实例方法,我会得到

+[FavoritesManager testMethod]: unrecognized selector sent to class 0x59198
Run Code Online (Sandbox Code Playgroud)

对于它的价值,这就是testMethod的样子:

- (void)testMethod {
    NSLog(@"Test");
}
Run Code Online (Sandbox Code Playgroud)

我绝对肯定它在界面中声明.我在其他类中使用了这个确切的代码,它就像一个魅力,所以我真的不明白这里的问题是什么.有一点可疑的是加号+[FavoritesManager testMethod],但我无法解释.有任何想法吗?

编辑:我混淆了公共/私人和类/方法术语.感谢所有指出这一点的人.

Tom*_*mmy 6

如果你想从另一个类方法调用testMethod,那么你需要:

+ (void)testMethod {
    NSLog(@"Test");
}
Run Code Online (Sandbox Code Playgroud)

原因是如果你调用一个类方法,那么就没有实例,所以没有什么可以调用实例方法.但可能你想打电话:

[[FavoritesManager sharedManager] testMethod];
Run Code Online (Sandbox Code Playgroud)

这意味着'获取共享实例,然后调用testMethod它'.在我输入时思考,您可能还想添加:

+ (void)forwardInvocation:(NSInvocation *)anInvocation
{
    id sharedManager = [self sharedManager];

    if ([sharedManager respondsToSelector:
            [anInvocation selector]])
        [anInvocation invokeWithTarget:sharedManager];
    else
        [super forwardInvocation:anInvocation];
}
Run Code Online (Sandbox Code Playgroud)

哪种是用于消息转发的Objective-C方法.因此,如果元类FavoritesManager接收到无法响应的消息,则允许其共享管理器实例进行操作.这意味着:

[FavoritesManager testMethod];
Run Code Online (Sandbox Code Playgroud)

变得功能相当(虽然慢一点):

[[FavoritesManager sharedManager] testMethod];
Run Code Online (Sandbox Code Playgroud)

假设除了实例方法之外还没有实现类方法.您可以在Apple官方文档中了解有关邮件转发的更多信息.