SKTexture EXC_BAD_ACCESS

迈克尔·肯特94

我正在开发SpriteKit游戏,并试图允许用户通过给游戏着色来自定义游戏中的飞船图像。

我添加了一个类别,以UIImage提供的实现adjustImage:hue:saturation:brightness它使用两个CIFilters进行调整。我知道该代码有效,因为我在另一个应用程序中使用UIImageView而不是进行了测试SKTexture

另请注意,这CSHeroShipNode是的子类SKSpriteNode

出现的问题是我在指示的行上访问不正确,我也不知道为什么。调试显示,即使传递到第二种方法中,图像和纹理在过程中的任何地方都永远不会为零。

以下代码来自CSHeroShipNode该类。

+(instancetype)heroShip {
    UIImage *textureImage = [UIImage adjustImage:[UIImage imageNamed:@"heroShip_0001.png"] hue:0.0 saturation:1.0 brightness:0.0];
    SKTexture *heroTexture = [SKTexture textureWithImage:textureImage];
    CSHeroShipNode *hero = [CSHeroShipNode shipWithTexture:heroTexture size:CGSizeMake(64, 64)];
    return hero;
}

+(instancetype)shipWithTexture:(SKTexture *)texture size:(CGSize)size {
    /***** this next line causes it to crash *****/
    CSHeroShipNode *ship = [CSHeroShipNode spriteNodeWithTexture:texture size:size];

    ... // set other properties

    return ship;
}

这是崩溃后的回溯。

* thread #1: tid = 0xb100f, 0x0000000102c2ee3d libsystem_platform.dylib`OSSpinLockLock + 7, queue = 'com.apple.main-thread, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x0000000102c2ee3d libsystem_platform.dylib`OSSpinLockLock + 7
frame #1: 0x00000001012edaa1 SpriteKit`SKSpinLockSync(int*, void () block_pointer) + 30
frame #2: 0x00000001012b6ce7 SpriteKit`-[SKTexture loadImageData] + 221
frame #3: 0x00000001012b921f SpriteKit`-[SKTexture size] + 33
frame #4: 0x00000001012d766c SpriteKit`-[SKSpriteNode initWithTexture:] + 96
frame #5: 0x00000001012d77d8 SpriteKit`+[SKSpriteNode spriteNodeWithTexture:] + 76
frame #6: 0x00000001012d7857 SpriteKit`+[SKSpriteNode spriteNodeWithTexture:size:] + 77
frame #7: 0x0000000100006b98 Space`+[CSHeroShipNode shipWithTexture:size:](self=0x0000000100022300, _cmd=0x000000010001753b, texture=0x0000000116354ab0, size=CGSize at 0x00007fff5fbfc7d8) + 136 at CSHeroShipNode.m:27
frame #8: 0x0000000100006a3f Space`+[CSHeroShipNode heroShip](self=0x0000000100022300, _cmd=0x00000001000175c9) + 287 at CSHeroShipNode.m:22
frame #9: 0x0000000100010d3e Space`-[CSSurvivalGameLevel getHeroShip](self=0x0000000116341bf0, _cmd=0x0000000100017a14) + 46 at CSSurvivalGameLevel.m:33
frame #10: 0x00000001000152c5 Space`+[CSWorldNode worldNodeWithLevel:scene:](self=0x0000000100022a80, _cmd=0x0000000100017be7, level=0x0000000116341bf0, scene=0x000000011634d490) + 837 at CSWorldNode.m:24
frame #11: 0x000000010000b8d2 Space`-[CSGameScene initWithSize:level:](self=0x000000011634d490, _cmd=0x0000000100017b24, size=CGSize at 0x00007fff5fbfcc80, level=0x0000000116341bf0) + 1202 at CSGameScene.m:70
frame #12: 0x000000010000b3f1 Space`+[CSGameScene gameSceneWithSize:level:](self=0x0000000100022530, _cmd=0x0000000100017a64, size=CGSize at 0x00007fff5fbfcce0, level=0x0000000116341bf0) + 113 at CSGameScene.m:47
frame #13: 0x0000000100014e65 Space`-[CSMainMenuScene newGame](self=0x000000010c0154d0, _cmd=0x00000001000187c0) + 133 at CSMainMenuScene.m:44
frame #14: 0x00000001000056c1 Space`-[CSButtonNode callAction](self=0x000000010c02a280, _cmd=0x00000001000173ab) + 209 at CSButtonNode.m:41
frame #15: 0x00000001000057d1 Space`-[CSButtonNode pressEnded](self=0x000000010c02a280, _cmd=0x0000000100017413) + 129 at CSButtonNode.m:52
frame #16: 0x00000001000064a4 Space`-[CSButtonNode touchesEnded:withEvent:](self=0x000000010c02a280, _cmd=0x0000000100a00ce3, touches=0x000000011634cd50, event=0x000000010c501460) + 772 at CSButtonNode.m:81
frame #17: 0x00000001012c0df4 SpriteKit`-[SKView touchesEnded:withEvent:] + 540
frame #18: 0x00000001003a3c15 UIKit`-[UIWindow _sendTouchesForEvent:] + 701
frame #19: 0x00000001003a4633 UIKit`-[UIWindow sendEvent:] + 988
frame #20: 0x000000010037dfa2 UIKit`-[UIApplication sendEvent:] + 211
frame #21: 0x000000010036bd7f UIKit`_UIApplicationHandleEventQueue + 9549
frame #22: 0x0000000101a5fec1 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
frame #23: 0x0000000101a5f792 CoreFoundation`__CFRunLoopDoSources0 + 242
frame #24: 0x0000000101a7b61f CoreFoundation`__CFRunLoopRun + 767
frame #25: 0x0000000101a7af33 CoreFoundation`CFRunLoopRunSpecific + 467
frame #26: 0x0000000101f063a0 GraphicsServices`GSEventRunModal + 161
frame #27: 0x000000010036e043 UIKit`UIApplicationMain + 1010
frame #28: 0x0000000100016253 Space`main(argc=1, argv=0x00007fff5fbfed28) + 115 at main.m:16
frame #29: 0x0000000102c255fd libdyld.dylib`start + 1
frame #30: 0x0000000102c255fd libdyld.dylib`start + 1

编辑:这是整个CSHeroShipNode班级。

#import "CSHeroShipNode.h"

#import "CSGameScene.h"
#import "CSPhaserNode.h"

@implementation CSHeroShipNode {
    SKEmitterNode *exhaust;
}

+(instancetype)heroShip {
    UIImage *textureImage = [UIImage adjustImage:[UIImage imageNamed:@"heroShip_0001.png"] hue:0.0 saturation:1.0 brightness:0.0];
    SKTexture *heroTexture = [SKTexture textureWithImage:textureImage];
    CSHeroShipNode *hero = [CSHeroShipNode shipWithTexture:heroTexture size:CGSizeMake(64, 64)];
    return hero;
}

+(instancetype)shipWithTexture:(SKTexture *)texture size:(CGSize)size {
    CSHeroShipNode *ship = [CSHeroShipNode spriteNodeWithTexture:texture size:size];

    ship.name = @"Hero";
    ship.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:size.width / 2];
    ship.physicsBody.categoryBitMask = CSPhysicsBodyCollisionTypeHeroShip;
    ship.physicsBody.collisionBitMask = CSPhysicsBodyCollisionTypeWorld;
    ship.physicsBody.contactTestBitMask = CSPhysicsBodyCollisionTypeEnemyPhaser | CSPhysicsBodyCollisionTypeEnemyShip | CSPhysicsBodyCollisionTypeObject;

    ship->exhaust = [NSKeyedUnarchiver unarchiveObjectWithFile:[[NSBundle mainBundle] pathForResource:@"Exhaust" ofType:@"sks"]];
    CGPoint exhaustPosition = CGPointMake(ship.position.x, ship.position.y - ship.size.height / 2 + 7);
    ship->exhaust.position = exhaustPosition;
    [ship addChild:ship->exhaust];

    // set the initial health
    ship.health = 200;

    ship.weaponCharge = 100;
    ship.weaponChargeRate = 100;

    return ship;
}

-(void)fireToLocation:(CGPoint)location atTime:(CFTimeInterval)gameTime {
    // delay phaser firing due to recharge time
    if (self.weaponCharge == 100) {
        lastFireTime = gameTime;
        self.weaponCharge = 0;

        float xOffset = location.x - self.position.x;
        float yOffset = location.y - self.position.y;
        float angle = atan2f(yOffset, xOffset);

        CSPhaserNode *phaser = [[CSPhaserNode alloc] initWithPosition:self.position angle:angle time:gameTime];
        phaser.parentShip = self;
        [((CSGameScene *)self.scene).world addChild:phaser];
    }
}

-(void)takeDamage:(NSUInteger)damage {
    self.health -= damage;
}

-(void)die {
    // make sure that health is 0
    self.health = 0;
    // create an explosion for the ship
    SKEmitterNode *explosion = [NSKeyedUnarchiver unarchiveObjectWithFile:[[NSBundle mainBundle] pathForResource:@"ShipExplosion" ofType:@"sks"]];
    explosion.position = self.position;
    [((CSGameScene *)self.scene).world addChild:explosion];
    [self removeFromParent];
}

-(void)update:(CFTimeInterval)gameTime {
    [super update:gameTime];
}


@end
迈克尔·肯特94

事实证明,这是SpriteKit代码中的错误(请参阅回答,问题非常相似)。“在lldb跟踪之后,我猜想这是一个内存管理问题,它在使用过滤器时如何分配图像数据缓冲区。”

我最终CIContext在我的adjustImage:hue:saturation:brightness:方法中使用来创建CGImageRef,然后将其返回。所以最终的代码CSHeroShipNode看起来像这样

+(instancetype)heroShip {
    CGImageRef textureImage = [UIImage adjustImage:[UIImage imageNamed:@"heroShip_0001.png"] hue:0.0 saturation:1.0 brightness:0.0];
    SKTexture *heroTexture = [SKTexture textureWithCGImage:textureImage];
    CSHeroShipNode *hero = [CSHeroShipNode shipWithTexture:heroTexture size:CGSizeMake(64, 64)];
    return hero;
}

尽管这种解决方法并不可怕,但我仍然感到烦恼的是,Apple的代码存在此类问题。希望他们会尽快解决。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

带有Swift 1.2的TextureFromNode的SKTexture的EXC_BAD_ACCESS错误

来自分类Dev

调试EXC_BAD_ACCESS

来自分类Dev

NSDictionary EXC_BAD_ACCESS

来自分类Dev

AFHTTPRequestOperationManager的EXC_BAD_ACCESS

来自分类Dev

EXC_BAD_ACCESS在mergeChangesFromContextDidSaveNotification

来自分类Dev

EXC_BAD_ACCESS StringWithFormat

来自分类Dev

EXC_BAD_ACCESS on iOS 8.1 with Dictionary

来自分类Dev

GCD / NSOperationQueue EXC_BAD_ACCESS

来自分类Dev

UIAlertController EXC_BAD_ACCESS错误-Swift

来自分类Dev

指向函数头的EXC_BAD_ACCESS

来自分类Dev

生成nspredicate时EXC_BAD_ACCESS

来自分类Dev

iOS EXC_BAD_ACCESS:如何调试?

来自分类Dev

迅速细分错误(EXC_BAD_ACCESS)

来自分类Dev

如何从EXC_BAD_ACCESS中恢复?

来自分类Dev

SKNode.removeFromParent()EXC_BAD_ACCESS

来自分类Dev

CGContextDrawLinearGradient导致EXC_BAD_ACCESS

来自分类Dev

CCHmac上的EXC_BAD_ACCESS

来自分类Dev

使用NativeCSS时EXC_BAD_ACCESS

来自分类Dev

在AVAssetReader中获取Exc_Bad_access

来自分类Dev

来自Apple Subthread的EXC_BAD_ACCESS

来自分类Dev

[UICollectionView setCollectionViewLayout:]上的EXC_BAD_ACCESS

来自分类Dev

使用协议组成的EXC_BAD_ACCESS

来自分类Dev

viewForAnnotation中的EXC_BAD_ACCESS

来自分类Dev

NSTableView与源,导致EXC_BAD_ACCESS

来自分类Dev

Swift中的UIWebView:exc_bad_access

来自分类Dev

MIDINetworkConnection EXC_BAD_ACCESS错误

来自分类Dev

Swift:animator()导致EXC_BAD_ACCESS

来自分类Dev

EXC_BAD_ACCESS Sprite套件

来自分类Dev

Swift中的UIDocumentInteractionControllerDelegate EXC_BAD_ACCESS