我来自Actionscript Background。在Actionscript类中,Method只能访问Class Methods和Class属性。
但在目标C中,
类方法gameResultAll如何访问实例方法initFromPlist
+(NSMutableArray *)gameResultAll://Class Method
-(id)initFromPlist:(id)plist;//Instance Method
NSMutableArray *gameResults = [GameResult gameResultAll]; // (returns GameResult array)
为什么调用[self init]方法而不是[super init]来从类方法创建实例。
提前致谢。
#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;
}
答案 0 :(得分:2)
在Actionscript中,Class Method只能访问Class Methods和Class属性。
在Objective-C中也没有什么不同(因为没有别的意义),所以:
类方法GameResultAll如何访问实例方法initFromPlist
仅通过有效的实例。
为什么调用
[self init]
方法而不是[self super]
来从类方法创建实例。
因为后者是语法错误,也许?阅读基本的Objective-C教程。
答案 1 :(得分:2)
你问:
类方法
gameResultAll
如何访问实例方法initFromPlist
它可以访问该方法,因为您使用了alloc
方法,该方法创建了GameResult
的实例。现在您有了一个实例,您可以将实例方法与此实例结合使用。
顺便说一下,这是一个非常常见的模式,一个“方便”类方法,它分配一个对象的实例(带alloc
)并初始化对象(使用init
或一些排列那)。或者,在这种情况下,它可以创建这些对象的数组。
然后你继续问:
为什么调用
[self init]
方法而不是[super init]
来从类方法创建实例。
我可以理解这种困惑,但这两者的行为有一个重要但微妙的区别。
想象一下这种情况:
在将来某个日期,您将GameResult
作为子类,例如ArcadeGameResult
;
您为init
实现了ArcadeGameResult
方法,该方法初始化了此子类特有的一些属性;以及
您碰巧初始化ArcadeGameResult
实例,如下所示:
ArcadeGameResult *agr = [[ArcadeGameResult alloc] initFromPlist:plist];
由于initFromPlist
使用[self init]
,这意味着initFromPlist
GameResult
方法将最终调用对象的init
方法(在这个例子中,实际上是一个ArcadeGameResult
对象)。但如果initFromPlist
中的GameResult
改为[super init]
,则不会调用ArcadeGameResult
的{{1}}方法,因此{{ 1}}如果与子类一起使用会有问题。
底线,除非您调用的方法是完全相同的方法签名,否则调用init
再现而不是initFromPlist
再现更安全。如果您决定在将来继承子类,它会更灵活一些。
律师有一个必然结果。从实例方法调用类方法时,应该引用self
而不是类名。所以,想象一下你的super
类有一个类方法:
[self class]
如果你有一些GameResult
实例方法可以利用这个方法,你可能会想写:
+ (void)someClassMethod
{
// do something
}
但这不是一个好主意。您将改为使用以下内容:
GameResult
它们看起来非常相似,但后者允许您在子类中实现- (void)someInstanceMethod
{
// do some stuff
[GameResult someClassMethod];
}
,并且此实例方法仍然有效。如果使用前一个构造,则- (void)someInstanceMethod
{
// do some stuff
[[self class] someClassMethod];
}
不会调用子类化方法。
这些是微妙的问题,可能对您当前的代码示例并不重要。但希望它能说明在这种情况下someClassMethod
与someInstanceMethod
的选择。