我正在学习iOS编程,并且对以下关于使用关键字self的代码感到困惑。
据我了解,self
就像Java的this
。它指的是当前实例。当我想调用类方法时,通常的方法应该是[PlayingCard validSuits];
但是在实例上入侵类方法也没关系,对吧?就像[self validSuits];
(我在课堂上所以自我指的是PlayCard的一个实例)
但是在下面的代码中,它在某个地方给出了错误,但在其他地方看起来不错。(由3条评论指出,这是在Xcode 5.1中)
我错过了什么吗?
(P.S。我想我遇到了与here类似的问题,但没有人回答。即使使用[PlayingCard 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
标题文件:
// PlayingCard.h
#import "Card.h"
@interface PlayingCard : Card
@property (nonatomic, strong) NSString *suit;
@property (nonatomic) NSUInteger rank;
+ (NSArray *) validSuits;
+ (NSUInteger) maxRank;
@end
答案 0 :(得分: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