在目标c中访问类方法.使用的是self还是classname? [英] Accessing class method in objective c. Using self or classname?
问题描述
我正在学习iOS编程,并且对以下有关关键字self的使用的代码感到困惑.
I am learning iOS programming and am confused by the following code regarding the use of keyword self.
根据我的理解, self
就像Java的 this
.它指的是当前实例.当我想调用类方法时,通常的方法应该类似于 [PlayingCard validSuits];
,但是也可以在实例上入侵类方法,对吗?就像 [self validSuits];
(我在课程中,self指的是PlayingCard的实例)
From my understanding, self
is like Java's this
. It refers to the current instance. When I want to call a class method, the usual way should be like [PlayingCard validSuits];
But it's also OK to invade a class method on an instance, right? Like [self validSuits];
(I am in the class so self refers to an instance of PlayingCard)
但是在下面的代码中,它在某处给出错误,但在其他地方看起来还可以.(由3条注释指出,这在Xcode 5.1中)
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.S. I think I am having the similar problem as here, which no one answered yet. He got the same error even using [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
推荐答案
如果要从(同一类的)类方法中调用另一个类方法,则可以使用 [self classMethod]
.但是,如果您在实例方法中,并且需要调用该类的类方法,则可以使用 [[[self class] classMethod]
If you are calling another class method from inside a class method (of the same class) you can just use [self classMethod]
. If however you are in an instance method and you need to call that classes class method you can use [[self class] classMethod]
@Martin R 指出的-如果您将 PlayingCard
子类化,则调用那么,在类方法中的 self
将是该子类,而不是 PlayingCard
.
As pointed out by @Martin R - if you subclass PlayingCard
, calling self
in a class method will then be that subclass and not PlayingCard
.
为完整起见,您需要执行以下操作:
For completeness you need to do:
// 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
这篇关于在目标c中访问类方法.使用的是self还是classname?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!