访问目标c中的类方法.使用自我或类名?

Wei*_*eng 9 compiler-errors objective-c class-method ios

我正在学习iOS编程,并且对以下使用关键字self的代码感到困惑.

从我的理解来看,self就像Java一样this.它指的是当前实例.当我想调用一个类方法时,通常的方法应该是这样 [PlayingCard validSuits];但是在一个实例上入侵类方法也没关系,对吧?喜欢[self validSuits];(我在课堂上所以自我指的是PlayCard的一个实例)

但是在下面的代码中,它在某个地方给出了错误但在别处看起来没问题.(由3条评论指出,这是在Xcode 5.1中)

我错过了什么吗?

(PS我想我是有类似的问题在这里,这是任何一个解答.他甚至得到了使用[游戏牌validSuits]同样的错误.)

//  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
Run Code Online (Sandbox Code Playgroud)

头文件:

//  PlayingCard.h

#import "Card.h"

@interface PlayingCard : Card

@property (nonatomic, strong) NSString *suit;
@property (nonatomic) NSUInteger rank;

+ (NSArray *) validSuits;
+ (NSUInteger) maxRank;

@end
Run Code Online (Sandbox Code Playgroud)

Ric*_*ich 19

如果从类方法(同一类)中调用另一个类方法,则可以使用[self classMethod].但是,如果您使用的是实例方法,则需要调用该类类方法[[self class] classMethod]

正如@Martin R指出的那样- 如果你是子类PlayingCard,那么调用self类方法将是那个子类而不是PlayingCard.

编辑:

为了完整性,您需要:

//  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 [[self rankStrings] count] -1; 
}

//override super class's method
- (NSString *)contents {

    NSArray *rankStrings = [[self class] rankStrings];  

    return [rankStrings[self.rank] stringByAppendingString:self.suit];
}

- (void) setSuit:(NSString *)suit {
    if ( [[[self class] validSuits] containsObject:suit]) {  
       _suit = suit;
    }
}

- (NSString *) suit {
    return _suit ? _suit : @"?";
}

@end
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果`self`是*子类*的实例,使用`[self class]而不是`ClassName`会产生影响. (2认同)
  • @WeishiZeng:如果self是PlayingCard的一个实例,那么[self class]就是PlayingCard,即使在父类Card的方法中调用也是如此. (2认同)