简体   繁体   English

类方法如何访问实例方法?

[英]How Class Method can access Instance Method ?

I am from Actionscript Background. 我来自Actionscript Background。 In Actionscript Class Method can access only Class Methods and Class properties. 在Actionscript类中,Method只能访问Class Methods和Class属性。

But In Objective C, 但在目标C中,

  1. How Class method gameResultAll can access Instance Method initFromPlist 类方法gameResultAll如何访问实例方法initFromPlist

     +(NSMutableArray *)gameResultAll://Class Method -(id)initFromPlist:(id)plist;//Instance Method NSMutableArray *gameResults = [GameResult gameResultAll]; // (returns GameResult array) 
  2. Why [self init] method is called instead of [super init] to create an instance from class method. 为什么调用[self init]方法而不是[super init]来从类方法创建实例。

Thanks in advance. 提前致谢。

#import "GameResult.h"

@implementation GameResult

#define GAME_RESULT_KEY @"gameresult_key"
#define SCORE_KEY @"score"

+(NSMutableArray *)gameResultAll
{

    NSMutableArray *resultArray = [[NSMutableArray alloc] init];
    for (id plist in [[[[NSUserDefaults standardUserDefaults] dictionaryForKey:GAME_RESULT_KEY] mutableCopy] allValues]) 
    {
        GameResult *gameResult = [[GameResult alloc] initFromPlist:plist];
        [resultArray addObject:gameResult];
    }
    return  resultArray;
}

//Designated initialiser
-(id)initFromPlist:(id)plist
{

    self = [self init];
    if(self)
    {
       if([plist isKindOfClass:[NSDictionary class]])
       {
           NSDictionary *resultDictionary = (NSDictionary*)plist;
           _score = (int)resultDictionary[SCORE_KEY];
       }
    }
    return  self;
}

In Actionscript Class Method can access only Class Methods and Class properties. 在Actionscript类中,Method只能访问Class Methods和Class属性。

That's not different in Objective-C either (because nothing else would make sense), so: 在Objective-C中也没有什么不同(因为没有别的东西是有意义的),所以:

How Class method GameResultAll can access Instance Method initFromPlist 类方法GameResultAll如何访问实例方法initFromPlist

Only through a valid instance. 只能通过有效的实例。

Why [self init] method is called instead of [self super] to create an instance from class method. 为什么调用[self init]方法而不是[self super]来从类方法创建实例。

Because the latter is a syntax error, perhaps? 因为后者是语法错误,也许? Read a basic Objective-C tutorial. 阅读基本的Objective-C教程。

You asked: 您询问:

How Class method gameResultAll can access Instance Method initFromPlist 类方法gameResultAll如何访问实例方法initFromPlist

It can access that method because you used the alloc method, which creates an instance of GameResult . 它可以访问该方法,因为您使用了alloc方法,该方法创建了GameResult的实例。 Now that you have an instance, you can use instance methods in conjunction with this instance. 现在您有了一个实例,您可以将实例方法与此实例结合使用。

By the way, this is a very common pattern, a "convenience" class method that allocates an instance of an object (with alloc ) and initializes the object (with init or some permutation of that). 顺便说一句,这是一个非常常见的模式,一个“方便”类方法,它分配一个对象的实例(带有alloc )并初始化该对象(使用init或其中的一些排列)。 Or, as in this case, it can create an array of these objects. 或者,在这种情况下,它可以创建这些对象的数组。

You then go on to ask: 然后你继续问:

Why [self init] method is called instead of [super init] to create an instance from class method. 为什么调用[self init]方法而不是[super init]来从类方法创建实例。

I can understand the confusion, but there is an important, yet subtle distinction in the behavior of these two. 我可以理解这种困惑,但这两者的行为有一个重要但微妙的区别。

Imagine this scenario: 想象一下这种情况:

  • At some future date, you subclass GameResult , eg ArcadeGameResult ; 在将来的某个日期,您将GameResult ,例如ArcadeGameResult ;

  • You implemented an init method for ArcadeGameResult that initializes some properties unique to this subclass; 您为ArcadeGameResult实现了一个init方法,该方法初始化了该子类特有的一些属性; and

  • You happen to initialize a ArcadeGameResult instance like so: 您碰巧初始化ArcadeGameResult实例,如下所示:

     ArcadeGameResult *agr = [[ArcadeGameResult alloc] initFromPlist:plist]; 

Because the initFromPlist uses [self init] , it means that the the initFromPlist method of GameResult will end up calling the init method of the object (which in this example, is actually a ArcadeGameResult object). 因为initFromPlist使用[self init] ,这意味着initFromPlist方法GameResult会调用对象的init方法(在本例中,实际上是一个ArcadeGameResult对象)。 But if initFromPlist in GameResult called [super init] instead, it would not have called ArcadeGameResult 's init method and thus initFromPlist would be problematic if ever used in conjunction with a subclass. 但是如果initFromPlist中的GameResult调用[super init] ,它就不会调用ArcadeGameResultinit方法,因此如果与子类一起使用initFromPlist会有问题。

Bottom line, unless the method you're calling is the exact same method signature, it's safer to call the self rendition rather than the super rendition. 最重要的是,除非您调用的方法是完全相同的方法签名,否则调用self呈现而不是super呈现会更安全。 It's a little more flexible in case you ever decide to subclass in the future. 如果你决定将来继承它,它会更灵活一些。


There is a corollary to the counsel. 律师有一个必然结果。 When calling class methods from an instance method, you should refer to [self class] rather than the class name. 从实例方法调用类方法时,应该引用[self class]而不是类名。 So, imagine your GameResult class had a class method: 所以,想象一下你的GameResult类有一个类方法:

+ (void)someClassMethod
{
    // do something
}

If you had some GameResult instance method that was going to avail itself of this method, you might be tempted to write: 如果你有一些GameResult实例方法可以利用这个方法,你可能会想写:

- (void)someInstanceMethod
{
    // do some stuff

    [GameResult someClassMethod];
}

But that's not a good idea. 但这不是一个好主意。 You would instead use the following: 您将改为使用以下内容:

- (void)someInstanceMethod
{
    // do some stuff

    [[self class] someClassMethod];
}

They look very similar, but the latter lets you implement a someClassMethod in a subclass, and this instance method will still work. 它们看起来非常相似,但后者允许您在子类中实现someClassMethod ,并且此实例方法仍然有效。 If you use the former construct, the subclassed class method wouldn't be called by someInstanceMethod . 如果使用前一个构造,则someInstanceMethod不会调用子类化方法。

These are subtle issues, and probably not critical for your current code sample. 这些是微妙的问题,可能对您当前的代码示例并不重要。 But hopefully it illuminates the choice of [self init] versus [super init] in this situation. 但希望它能说明在这种情况下[self init][super init]的选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM