2012-03-01 42 views
0

我有如下实例化一个单例类:Objective-C的单只响应类方法

#import "FavoritesManager.h" 

static FavoritesManager *sharedFavoritesManager = nil; 

@implementation FavoritesManager 

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

    return self; 
} 

这返回一个对象,但由于某些原因,它只会类的方法作出回应。如果我把一个实例方法,我得到

+[FavoritesManager testMethod]: unrecognized selector sent to class 0x59198 

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

- (void)testMethod { 
    NSLog(@"Test"); 
} 

,我敢保证,它的接口中声明。我在其他类中使用了这个确切的代码,它的作用就像一个魅力,所以我真的不明白问题在这里。有一点是可疑的是+[FavoritesManager testMethod]的加号,但我无法解释它。有任何想法吗?

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

+0

您将公共方法与Class方法和私有方法混淆在实例方法中。 – dbrajkovic 2012-03-01 21:09:08

回答

4

的错误表明您发送的消息testMethod到类,而不是一个实例。

原因是您的sharedManager方法不正确。你目前正在返回self,在这个类的方法中,它本身就是类。这意味着当你编写[[FavoritesManager sharedManger] testMethod]时,你最终会发送testMethod给班级。由于testMethod不是类方法,因此会出现错误。

您应该在sharedManager的末尾有return sharedFavoritesManager;,而不是return self;。后者在实例方法初始化器中是正确的。

此外,正如dbrajkovic所评论的,您似乎对公共/私有和类/实例方法感到困惑。严格来说,ObjC没有私人方法。您可以隐藏声明,这会导致编译器警告,但该消息仍将被发送,并且该方法将被调用。 +-将类方法与实例方法区分开来;区别在于你发送消息的对象是哪种类型。这里的信息:What is the difference between class and instance methods?

6

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

+ (void)testMethod { 
    NSLog(@"Test"); 
} 

的原因是,如果你调用一个类方法,那么就没有实例,所以没有在其上调用实例方法。但可能你要拨打:

[[FavoritesManager sharedManager] testMethod]; 

这意味着“得到共享实例,然后调用testMethod就可以了”。按照我输入的方式思考,您可能还想补充:

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

    if ([sharedManager respondsToSelector: 
      [anInvocation selector]]) 
     [anInvocation invokeWithTarget:sharedManager]; 
    else 
     [super forwardInvocation:anInvocation]; 
} 

这是Objective-C的消息转发方式。因此,如果元类FavoritesManager收到它无法响应的消息,它会让它的共享管理器实例发挥作用。这意味着:

[FavoritesManager testMethod]; 

变为功能上等同于(虽然有点慢于):

[[FavoritesManager sharedManager] testMethod]; 

提供你还没有实现,除了一个实例方法一类方法。您可以在Apple's official documentation中了解有关邮件转发的更多信息。

1

+在方法声明的开始处意味着它是一个类方法, - 意味着它是一个实例方法。如果你想调用TestMethod的您sharedManager,然后保持TestMethod的声明,因为你拥有它,而是改变你的调用到

[[FavoritesManager sharedFavoritesManager] testMethod]; 

要么将​​工作,和之间选择

+(void)testMethod { 
    NSLog(@"Test"); 
} 

:这样做两个是应用程序设计的问题。

0

obj-c中没有特别的方法。 但无论如何,你总是在课堂外打电话,所以只声明“公共方法”。详细的帮助发布你的代码。

1

而是尝试

[[FavoritesManager sharedFavoritesManager] testMethod]; 
2

错误是正确的,你必须调用[FavoritesManager testMethod]这意味着你正在尝试调用类方法。我相信你想[[FavoritesManager sharedManager] testMethod];

0

打电话给你的单一实例:

[FavoritesManager sharedManager] TestMethod的]。