我正在创建一个自定义模式层。这个想法是用户看到一个城市,点击该城市并接受或拒绝该位置。
我NSMethodSignature
用来处理回调,所以我知道用户是点击了模态层中的Tick
(接受)还是Cross
(拒绝)按钮。
但是,由于某种原因,应用程序在调用回调后会崩溃,并在从模式返回时给我一个错误的访问错误。
0x000d584e <+0174> mov %eax,0x4(%esp)
0x000d5852 <+0178> call 0xd6006 <dyld_stub_objc_msgSend>
0x000d5857 <+0183> mov -0x8(%ebp),%eax Thread 1: Program received signal: EXC_BAD_ACCESS
我不明白为什么会发生这种情况,因为城市对象是在类中定义的。
例如,我的 .h 文件有:
@interface MapMenuLayer : CCLayer
{
CCArray *listOfCities;
City *city;
}
@property (nonatomic, retain) CCArray *listOfCities;
@property (nonatomic, retain) City *city;
我的 .m 文件有:
@synthesize listOfCities, city;
稍后我将页面上每个城市的显示定义为可点击CCMenu
项目。当用户点击一个城市时,它会调用:
-(void) onMenuItem:(id)sender
{
NSLog(@"sender = %d", [sender tag]);
self.city = [self.listOfCities objectAtIndex:[sender tag]];
NSString *cityName = self.city.name;
NSLog(@"cityName = %@", cityName);
// Launch the modal layer
CityModalLayer *cityModalLayer = [[[CityModalLayer alloc] initWithCity:self.city target:self selector:@selector(onDialogButton:)] autorelease];
[cityModalLayer show:self];
}
// This is called when the modal is closed or actioned upon
- (void) onDialogButton:(NSInteger)buttonIndex
{
NSLog(@"onDialogButton:buttonIndex: %d", buttonIndex);
NSString *cityName = self.city.name;
NSLog(@"You selected: cityName = %@", cityName);
}
当应用程序流从模态层返回并启动onDialogButton
方法时发生错误访问错误。
它输出日志很好,但是当它碰到城市对象时它会崩溃。我不知道为什么会发生这种情况,它不应该为空或导致任何形式错误。
好的,所以模态层有点复杂,但为了这个问题,我把它删掉了:
-(id) initWithCity:(City *)cityObj target:(id)target selector:(SEL)selector
{
if((self=[super init]))
{
[self initWithColor:ccc4(0, 0, 0, 255)];
[self setOpacity:80];
[self setIsTouchEnabled:YES];
self.city = cityObj;
// Setup the signature class
NSMethodSignature *sig = [[target class] instanceMethodSignatureForSelector:selector];
callback = [NSInvocation invocationWithMethodSignature:sig];
[callback setTarget:target];
[callback setSelector:selector];
[callback retain];
// -----
// MENU
// The frames are not in this code, but they do exist
// Add modal menu
// Modal Menu (Tick/Cross)
CCMenu *modalMenu = [CCMenu menuWithItems:nil];
CCSprite *closeButtonOff = [CCSprite spriteWithSpriteFrameName:@"closeButton_Off.png"];
CCSprite *closeButtonOn = [CCSprite spriteWithSpriteFrameName:@"closeButton_On.png"];
CCSprite *tickButtonOff = [CCSprite spriteWithSpriteFrameName:@"tickButton_Off.png"];
CCSprite *tickButtonOn = [CCSprite spriteWithSpriteFrameName:@"tickButton_On.png"];
// Tick button
CCMenuItemSprite *tickBtnItem = [CCMenuItemSprite itemFromNormalSprite:tickButtonOff selectedSprite:tickButtonOn target:self selector:@selector(onButtonPressed:)];
[tickBtnItem setTag:1];
[tickBtnItem setPosition:CGPointMake(130, -95)];
[tickBtnItem setIsEnabled:YES];
// Close button
CCMenuItemSprite *closeBtnItem = [CCMenuItemSprite itemFromNormalSprite:closeButtonOff selectedSprite:closeButtonOn target:self selector:@selector(onButtonPressed:)];
[closeBtnItem setTag:0];
[closeBtnItem setPosition:CGPointMake(-130, -95)];
[closeBtnItem setIsEnabled:YES];
// Add stuff to modal
[modalMenu addChild:closeBtnItem];
[modalMenu addChild:tickBtnItem];
// Add menu to the modalFrame
[modalFrame addChild:modalMenu z:2];
// --
// Add modalFrame to modalLayer
[self addChild:modalFrame];
} // end if
return self;
}
// This invokes the action
-(void) onButtonPressed:(id) sender
{
NSInteger buttonIndex = [sender tag];
NSLog(@"onButtonPressed: %d", buttonIndex);
[callback setArgument:&buttonIndex atIndex:1];
[callback invoke];
[self removeFromParentAndCleanup:YES];
}
-(void) dealloc
{
[callback release];
[super dealloc];
}
我已将问题跟踪到调用回调的时间,但是我不明白为什么它会崩溃或给我错误。它应该仍然在内存中有城市对象吗?
这可能是什么原因造成的?