Quickly expand convenience initializer for SKPhysicsBody

extension SKPhysicsBody { /// anchorPoint version of init(rectangleOfSize:center:) convenience init(rectangleOfSize s: CGSize, withAnchorPoint anchorPoint: CGPoint) { var center = CGPoint() center.x = (s.width / 2) - ( s.width * anchorPoint.x) center.y = (s.height / 2 ) - ( s.height * anchorPoint.y) self.init(rectangleOfSize: s, center: center) } } 

I got this runtime error

 -[PKPhysicsBody initWithRectangleOfSize:withAnchorPoint:]: unrecognized selector sent to instance 0x7f9b03c4fff0 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[PKPhysicsBody initWithRectangleOfSize:withAnchorPoint:]: unrecognized selector sent to instance 0x7f9b03c4fff0' 

This is how I call the code

 // redBox is a typical SKSpriteNode() redBox.physicsBody = SKPhysicsBody(rectangleOfSize: redBox.frame.size, withAnchorPoint: redBox.anchorPoint) 

I basically want to extend the SKPhysicsBody class to provide a convenience initializer to its factory method

+3
source share
1 answer

As @Cristik noted in the comments, this is one and the same root problem: this question and this question : the public class SKPhysicsBody is a convenient interface for the private PKPhysicsBody class that provides its implementation.

In the past, this approach was largely based on the "duck typing" behavior of Objective-C - if ClassA responds for all the same selectors as ClassB , you can call any of these selectors on a pointer whose static type (the type declared to the compiler in source code) is equal to ClassB , even if the actual object at run time is really an instance of ClassA .

Swift is more strict about the correct type of runtime than ObjC, so duck print is not enough. Since iOS 9 / OS X 10.11, SpriteKit has some workarounds that allow PKPhysicsBody instances to pretend to be SKPhysicsBody instances SKPhysicsBody .

But this does not apply to all cases - in particular, it does not catch (ObjC) [SKPhysicsBody alloc] returns an instance of PKPhysicsBody , which means that any attempt to add initializers to SKPhysicsBody in Swift will fail. (Since the ObjC alloc / init process comes down to a single initialization call in Swift.)

I would consider this error and recommend passing it to Apple .


Change / update: And until this error is fixed (it was a year and some are now), the workaround is to use the β€œinitializer” in the class method instead. (Or a global function if you need to, but ... ewww.)

+7
source

Source: https://habr.com/ru/post/972989/


All Articles