问题
I have the problem that touchesEnded (on iOS) or mouseUp (on macOS) is still called on released objects when the touch/click was started before the release. This behavior is causing crashes in my project. I made a stripped down program with SceneKit and a SpriteKit overlay but I am not sure what I am doing wrong.
I've started with the SceneKit game template (iOS or macOS) and I've added two classes:
In GameViewController.m at the end of -(void)awakeFromNib I added this:
OverlayScene *overlay=[OverlayScene sceneWithSize:self.gameView.frame.size];// init the overlay
[overlay setupButtons];// create a small GUI menu
[self.gameView setOverlaySKScene:overlay];// add the overlay to the SceneKit view
Then the two classes OverlayScene.m:
#import <SpriteKit/SpriteKit.h>
#import "Button.h"
@interface OverlayScene : SKScene
-(void)setupButtons;
@end
OverlayScene.m:
#import "OverlayScene.h"
@implementation OverlayScene
-(void)setupButtons{//showing a menu mockup
NSLog(@"setupButtons");
srand((unsigned)time(NULL));// seed the RNG
[self removeAllChildren];//remove all GUI element (only one button or nothing (in the first call)
Button *b=[[Button alloc] initWithSelector:@selector(setupButtons) onObject:self];// a new button
b.position=CGPointMake(rand()%300, rand()%300);// just a random position so we can see the change
[self addChild:b];// finally attach the button to the scene
}
@end
Button.h:
#import <SpriteKit/SpriteKit.h>
@interface Button : SKSpriteNode{
SEL selector;//the method which is supposed to be called by the button
__weak id selectorObj;//the object on which the selector is called
}
-(id)initWithSelector:(SEL)s onObject:(__weak id)o;
@end
Button.m:
#import "Button.h"
@implementation Button
-(id)initWithSelector:(SEL)s onObject:(__weak id)o{
//self=[super initWithColor:[UIColor purpleColor] size:CGSizeMake(200, 60)];//this is the code for iOS
self=[super initWithColor:[NSColor purpleColor] size:CGSizeMake(200, 60)];// this is for macOS
selector=s;//keep the selector with the button
selectorObj=o;
[self setUserInteractionEnabled:YES];//enable touch handling
return self;
}
//-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{//called on iOS
-(void)mouseDown:(NSEvent *)event{//called on macOS
[selectorObj performSelector:selector];//we are calling the method which was given during the button initialization
}
@end
When you click on the button it gets removed (and dealloced by arc) as expected and a new one is created. Everything is fine as long as you keep holding down the mouse button. When you release it the app crashes because that mouseUp event is sent to the removed button:
来源:https://stackoverflow.com/questions/39935505/spritekit-touchesended-mouseup-sent-to-released-object