2012-03-01 33 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的]。