Accessing class method in objective c. Using self or classname?

混江龙づ霸主 提交于 2021-01-21 17:50:02

问题


I am learning iOS programming and am confused by the following code regarding the use of keyword self.

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)

But in the following code, it gives error somewhere but looks ok elsewhere.(Pointed out by 3 comments, this is within Xcode 5.1)

Am I missing anything?

(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

The header file:

//  PlayingCard.h

#import "Card.h"

@interface PlayingCard : Card

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

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

@end

回答1:


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]

As pointed out by @Martin R - if you subclass PlayingCard, calling self in a class method will then be that subclass and not PlayingCard.

EDIT:

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


来源:https://stackoverflow.com/questions/23036604/accessing-class-method-in-objective-c-using-self-or-classname

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!