title: Accessing class method in objective c. Using self or classname?
body: <p>I am learning iOS programming and am confused by the following code regarding the use of keyword self.</p>
  
  <p>From my understanding, <code>self</code> is like Java's <code>this</code>. It refers to the current instance. When I want to call a class method, the usual way should be like  <code>[PlayingCard validSuits];</code> But it's also OK to invade a class method on an instance, right? Like <code>[self validSuits];</code> (I am in the class so self refers to an instance of PlayingCard)</p>
  
  <p>But in the following code, it gives error somewhere but looks ok elsewhere.(Pointed out by 3 comments, this is within Xcode 5.1) </p>
  
  <p>Am I missing anything? </p>
  
  <p>(P.S. I think I am having the similar problem as <a href="https://stackoverflow.com/questions/22660042/no-known-class-method-for-selector-validsuits-error-in-xcode-5-1">here</a>, which no one answered yet. He got the same error even using [PlayingCard validSuits]. )</p>
  
  <pre><code>//  PlayingCard.m
  
  #import "PlayingCard.h"
  
  @implementation PlayingCard
  @synthesize suit = _suit; 
  
  + (NSArray *)validSuits {
      return @[@"♠︎", @"♣︎", @"♥︎", @"♦︎"];
  }
  
  + (NSArray *)rankStrings {
      return @[@"?", @"A", @"2", @"3", @"4",@"5",@"6",@"7",@"8",@"9",@"10",@"J",@"Q",@"K"];
  
  }
  
  + (NSUInteger)maxRank {
      return [[PlayingCard rankStrings] count] -1; 
            //1. [self rankStrings] works fine.** 
  }
  
  
  //override super class's method
  - (NSString *)contents {
  
      NSArray *rankStrings = [PlayingCard rankStrings];  
             //2. if change rankStrings to self, then error:
             //No visible @interface for 'PlayingCard' declares the selector 'rankStrings'
  
      return [rankStrings[self.rank] stringByAppendingString:self.suit];
  }
  
  - (void) setSuit:(NSString *)suit {
      if ( [[PlayingCard validSuits] containsObject:suit]) {  
          //3.error when changed to [self validsuits] 
          //No visible @interface for 'PlayingCard' declares the selector 'validsuits'**
         _suit = suit;
      }
  
  }
  
  - (NSString *) suit {
      return _suit ? _suit : @"?";
  }
  
  @end
  </code></pre>
  
  <p>The header file:</p>
  
  <pre><code>//  PlayingCard.h
  
  #import "Card.h"
  
  @interface PlayingCard : Card
  
  @property (nonatomic, strong) NSString *suit;
  @property (nonatomic) NSUInteger rank;
  
  + (NSArray *) validSuits;
  + (NSUInteger) maxRank;
  
  @end
  </code></pre>