Ios 从Obj-C中的其他类访问实例方法
首先,我使用的是游戏引擎Ios 从Obj-C中的其他类访问实例方法,ios,objective-c,xcode,methods,levelhelper,Ios,Objective C,Xcode,Methods,Levelhelper,首先,我使用的是游戏引擎LevelHelper 有人知道从另一个类访问实例化的LevelHelperhelper类的正确方法吗 例如: 我有我的主要gameLayer类和hudLayer类。正在导入hudLayer类,并在gameLayer类中实例化。但是,我需要能够使用gameLayer类访问和操作hudLayer类中加载的sprite 建议我使用LevelHelperhelper实例方法。因此,我在hudLayer类中创建实例方法,然后在init方法中调用它来加载精灵。我尝试将此方法用作实例
LevelHelper
有人知道从另一个类访问实例化的LevelHelper
helper类的正确方法吗
例如:
我有我的主要gameLayer
类和hudLayer
类。正在导入hudLayer
类,并在gameLayer
类中实例化。但是,我需要能够使用gameLayer
类访问和操作hudLayer
类中加载的sprite
建议我使用LevelHelper
helper实例方法。因此,我在hudLayer类中创建实例方法,然后在init
方法中调用它来加载精灵。我尝试将此方法用作实例方法,但出现了一个错误,称为unrecognized selector
+[hudLayer hudLoader];
如果我尝试将该方法用作类方法,则会出现EXC\u BAD\u ACCESS
错误
我似乎找不到解决办法
我的代码:
+(LevelHelperLoader*)hudLoader;
+(LevelHelperLoader*)hudLoader
{
LevelHelperLoader* lh;
finishScreen = [lh spriteWithUniqueName:@"finishScreen"];
return lh;
}
LHSprite* finishScreen;
#import hudLayer.h
-(id) init {
[self retrieveRequiredObjects];
}
-(void) retrieveRequiredObjects {
finishScreen = [[hudLayer hudLoader] spriteWithUniqueName:@"finishScreen"];
NSAssert(finishScreen!=nil, @"Couldn't find the menu!");
}
hudLayer.h:
+(LevelHelperLoader*)hudLoader;
+(LevelHelperLoader*)hudLoader
{
LevelHelperLoader* lh;
finishScreen = [lh spriteWithUniqueName:@"finishScreen"];
return lh;
}
LHSprite* finishScreen;
#import hudLayer.h
-(id) init {
[self retrieveRequiredObjects];
}
-(void) retrieveRequiredObjects {
finishScreen = [[hudLayer hudLoader] spriteWithUniqueName:@"finishScreen"];
NSAssert(finishScreen!=nil, @"Couldn't find the menu!");
}
hudLayer.mm:
+(LevelHelperLoader*)hudLoader;
+(LevelHelperLoader*)hudLoader
{
LevelHelperLoader* lh;
finishScreen = [lh spriteWithUniqueName:@"finishScreen"];
return lh;
}
LHSprite* finishScreen;
#import hudLayer.h
-(id) init {
[self retrieveRequiredObjects];
}
-(void) retrieveRequiredObjects {
finishScreen = [[hudLayer hudLoader] spriteWithUniqueName:@"finishScreen"];
NSAssert(finishScreen!=nil, @"Couldn't find the menu!");
}
gameLayer.h:
+(LevelHelperLoader*)hudLoader;
+(LevelHelperLoader*)hudLoader
{
LevelHelperLoader* lh;
finishScreen = [lh spriteWithUniqueName:@"finishScreen"];
return lh;
}
LHSprite* finishScreen;
#import hudLayer.h
-(id) init {
[self retrieveRequiredObjects];
}
-(void) retrieveRequiredObjects {
finishScreen = [[hudLayer hudLoader] spriteWithUniqueName:@"finishScreen"];
NSAssert(finishScreen!=nil, @"Couldn't find the menu!");
}
gameLayer.mm:
+(LevelHelperLoader*)hudLoader;
+(LevelHelperLoader*)hudLoader
{
LevelHelperLoader* lh;
finishScreen = [lh spriteWithUniqueName:@"finishScreen"];
return lh;
}
LHSprite* finishScreen;
#import hudLayer.h
-(id) init {
[self retrieveRequiredObjects];
}
-(void) retrieveRequiredObjects {
finishScreen = [[hudLayer hudLoader] spriteWithUniqueName:@"finishScreen"];
NSAssert(finishScreen!=nil, @"Couldn't find the menu!");
}
注意:这段代码只是为了确保我的逻辑和实现是正确的
非常感谢您的帮助。您是否尝试在调试器中单步执行代码,以准确查找导致崩溃的行 在我看来,它似乎就在这里:
LevelHelperLoader* lh;
finishScreen = [lh spriteWithUniqueName:@"finishScreen"];
您已声明1h,但尚未创建它。因此,您正在向一个不存在的对象发送消息
至少是这样
LevelHelperLoader* lh = [[LevelHelperLoader alloc] init];
会有帮助的
粗略地看一眼会添加更多细节:
LevelHelperLoader* loader = [[LevelHelperLoader alloc] initWithContentOfFile:@"level1"];
在文档中,这是一个实例变量-这表明hudLoader应该是一个实例方法,而不是类方法:
- (LevelHelperLoader*) hudLoader;
您应该在hudLoader初始化器中创建LevelHelperLoader*实例
更新
你在评论中说:
我调用的hudLayer.mm的init方法的内部 在我的 我不确定这是不是因为读了我的答案。然而,这里还有一些想法 首先,你能整理一下你的命名习惯吗。课程应该以大写字母开始 HudLayer.h
@interface
@property (strong) Hudlayer* hudLayer;
@end
@interface
@property (strong) LevelHelperLoader* levelHelper;
@end
让我们将此lh
实例变量声明为@interface中的属性,并改进其名称:
@property (strong) LevelHelperLoader* levelHelper
HudLayer.mm
-(id) init {
_hudLayer = [[Hudlayer alloc] init];
[self retrieveRequiredObjects];
}
-(void) retrieveRequiredObjects {
finishScreen = [self.hudLayer.levelHelper spriteWithUniqueName:@"finishScreen"];
NSAssert(finishScreen!=nil, @"Couldn't find the menu!");
}
-(id) init {
_levelHelper = [[LevelHelperLoader alloc] initWithContentOfFile:@"level1"];
[self retrieveRequiredObjects];
}
-(void) retrieveRequiredObjects {
finishScreen = [self.levelHelper spriteWithUniqueName:@"finishScreen"];
NSAssert(finishScreen!=nil, @"Couldn't find the menu!");
}
允许它自动合成或在@implementation中合成为:
@synthesize levelHelper = _levelHelper;
然后在init方法中
_levelHelper = [[LevelHelperLoader alloc] initWithContentOfFile:@"level1"];
并且hudLoader
成为
-(LevelHelperLoader*)hudLoader
{
finishScreen = [self.levelHelper spriteWithUniqueName:@"finishScreen"];
return self.levelHelper;
}
然后问问自己,-hudLoader
到底在做什么?分配给完成屏幕的行
?finishscreen
是iVar吗?你需要它吗?也许不是。除此之外,-hudLoader
所做的就是返回已经创建的LevelHelperLoader实例。既然您的iVar是一个属性,您就可以使用点符号属性语法从gameLayer访问它,并删除hudLoader
:
GameLayer.h
@interface
@property (strong) Hudlayer* hudLayer;
@end
@interface
@property (strong) LevelHelperLoader* levelHelper;
@end
GameLayer.m
-(id) init {
_hudLayer = [[Hudlayer alloc] init];
[self retrieveRequiredObjects];
}
-(void) retrieveRequiredObjects {
finishScreen = [self.hudLayer.levelHelper spriteWithUniqueName:@"finishScreen"];
NSAssert(finishScreen!=nil, @"Couldn't find the menu!");
}
-(id) init {
_levelHelper = [[LevelHelperLoader alloc] initWithContentOfFile:@"level1"];
[self retrieveRequiredObjects];
}
-(void) retrieveRequiredObjects {
finishScreen = [self.levelHelper spriteWithUniqueName:@"finishScreen"];
NSAssert(finishScreen!=nil, @"Couldn't find the menu!");
}
这让我想知道您是否需要一个hudLayer类(也许它正在做其他有用的工作)。。。看起来您可以直接从gameLayer获得levelHelper
GameLayer.h
@interface
@property (strong) Hudlayer* hudLayer;
@end
@interface
@property (strong) LevelHelperLoader* levelHelper;
@end
GameLayer.m
-(id) init {
_hudLayer = [[Hudlayer alloc] init];
[self retrieveRequiredObjects];
}
-(void) retrieveRequiredObjects {
finishScreen = [self.hudLayer.levelHelper spriteWithUniqueName:@"finishScreen"];
NSAssert(finishScreen!=nil, @"Couldn't find the menu!");
}
-(id) init {
_levelHelper = [[LevelHelperLoader alloc] initWithContentOfFile:@"level1"];
[self retrieveRequiredObjects];
}
-(void) retrieveRequiredObjects {
finishScreen = [self.levelHelper spriteWithUniqueName:@"finishScreen"];
NSAssert(finishScreen!=nil, @"Couldn't find the menu!");
}
最后,我不是建议您逐行遵循此代码,因为我不知道您项目的更广泛背景。但您确实需要理清类和实例、分配、实例化、局部变量和实例变量之间的混淆。请注意命名约定,以便您知道何时向类或该类的实例发送消息,以及何时直接或通过@property(例如self.property)寻址iVar_。保持一致。想想一门课实际上为你做了什么 在hudLayer.mm的init方法内部,我调用lh=[[LevelHelperLoader alloc]initWithContentOfFile:@“level1”];在.h中,我有LevelHelperLoader*lh;谢谢你的帮助,我会做出你建议的改变,看看它是如何工作的。在我的GameLayer.m中,我根据角色位置移动视图,因此如果我在该层上有hud,hud将被移出视图。为了解决这个问题,我为游戏中应该始终显示在屏幕上的资产创建了单独的类。但是,当加载了GameLayer.m的精灵出现问题时,我需要对加载在HudLayer.m中的精灵进行更改。因此,为了做到这一点,我需要GameLayer能够访问这些精灵,然后在HudLayer中更改它们。我还想到了使用NSUserDefaults更改布尔值并将其保存在GameLayer.h中,然后让HudLayer不断加载并检查布尔值,但我不确定这是否对我的知识节约非常有效,因为我可能是一个资源消耗者。