SpriteKit: NSInvalidArgumentException - Attempted to add a SKNode which already has parent - objective-c

I'm creating a game in SpriteKit using Objective-C. I am trying to generate blocks for the screen to be used in the game.
I'm getting an application crash on start up:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attemped to add a SKNode which already has a parent: <SKSpriteNode> name:'Block-0.000000-440.000000' texture:['nil'] position:{0, 440} size:{64, 64} rotation:0.00'
*** First throw call stack:
(
0 CoreFoundation 0x00891df6 __exceptionPreprocess + 182
1 libobjc.A.dylib 0x0051ba97 objc_exception_throw + 44
2 CoreFoundation 0x00891d1d +[NSException raise:format:] + 141
3 SpriteKit 0x00e8c94c -[SKNode addChild:] + 119
4 Hidden Route 0x0003b3c1 -[GameScene didMoveToView:] + 2417
5 SpriteKit 0x00e6031b -[SKScene _didMoveToView:] + 97
6 SpriteKit 0x00e7b157 -[SKView presentScene:] + 283
7 Hidden Route 0x00039e9e -[GameViewController viewDidLoad] + 526
8 UIKit 0x0115ad54 -[UIViewController loadViewIfRequired] + 771
9 UIKit 0x0115b045 -[UIViewController view] + 35
10 UIKit 0x0105f477 -[UIWindow handleStatusBarChangeFromHeight:toHeight:] + 879
11 UIKit 0x0106252d +[UIWindow _noteStatusBarHeightChanged:oldHeight:forAutolayoutRootViewsOnly:] + 273
12 UIKit 0x01006ad1 __79-[UIApplication _setStatusBarHidden:animationParameters:changeApplicationFlag:]_block_invoke + 163
13 UIKit 0x010862c6 +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 494
14 UIKit 0x01086701 +[UIView(UIViewAnimationWithBlocks) animateWithDuration:animations:completion:] + 115
15 UIKit 0x0100699e -[UIApplication _setStatusBarHidden:animationParameters:changeApplicationFlag:] + 506
16 UIKit 0x01006128 -[UIApplication _updateCurrentStatusBarViewControllerAppearance] + 286
17 UIKit 0x0105223a -[UIWindow _updateContextOrderingAndSetLayerHidden:] + 548
18 UIKit 0x0105319e -[UIWindow _setHidden:forced:] + 257
19 UIKit 0x01053473 -[UIWindow _orderFrontWithoutMakingKey] + 49
20 UIKit 0x01061615 -[UIWindow makeKeyAndVisible] + 80
21 UIKit 0x00ffecd6 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 3108
22 UIKit 0x0100216d -[UIApplication _runWithMainScene:transitionContext:completion:] + 1639
23 UIKit 0x0101ad30 __84-[UIApplication _handleApplicationActivationWithScene:transitionContext:completion:]_block_invoke + 59
24 UIKit 0x01000d7f -[UIApplication workspaceDidEndTransaction:] + 155
25 FrontBoardServices 0x06f909de __37-[FBSWorkspace clientEndTransaction:]_block_invoke_2 + 71
26 FrontBoardServices 0x06f9046f __40-[FBSWorkspace _performDelegateCallOut:]_block_invoke + 54
27 FrontBoardServices 0x06fa2425 __31-[FBSSerialQueue performAsync:]_block_invoke + 26
28 CoreFoundation 0x007b57a0 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 16
29 CoreFoundation 0x007ab0b3 __CFRunLoopDoBlocks + 195
30 CoreFoundation 0x007aaf0b __CFRunLoopRun + 2715
31 CoreFoundation 0x007aa1ab CFRunLoopRunSpecific + 443
32 CoreFoundation 0x007a9fdb CFRunLoopRunInMode + 123
33 UIKit 0x01000744 -[UIApplication _run] + 571
34 UIKit 0x01003e16 UIApplicationMain + 1526
35 Hidden Route 0x0003c41d main + 141
36 libdyld.dylib 0x02fa0ac9 start + 1
37 ??? 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
I've looked at the stack trace and found that the method causing the issue is my didMoveToView: method, which is this:
-(void)didMoveToView:(SKView *)view
{
// ViewDidLoad
[self initialize];
/* Setup your scene here
SKLabelNode *myLabel = [SKLabelNode labelNodeWithFontNamed:#"Arial"];
myLabel.text = #"Hello, World!";
myLabel.fontSize = 65;
myLabel.position = CGPointMake(CGRectGetMidX(self.frame),
CGRectGetMidY(self.frame));
*/
player = [SKSpriteNode spriteNodeWithColor:[AppDelegate getRandomColor] size:CGSizeMake(40, 40)];
player.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
[self generateBoard];
[self generateNextAtIndex:kNeed - 3];
int width = (self.frame.size.width) / [AppDelegate numberOfColumns];
int height = (self.frame.size.height) / kNeed;
for (int i = 0; i < boardRows.count; i++)
{
Row *current = [boardRows objectAtIndex:i];
for (int j = 0; j < current.blocks.count; j++)
{
Block *block = [current.blocks objectAtIndex:j];
block.anchorPoint = CGPointMake(0, 1);
block.position = CGPointMake((j * width), self.frame.size.height - (i * width));
[block setName:[NSString stringWithFormat:#"Block-%f-%f", block.position.x, block.position.y]];
NSLog(#"Position for item %i", i);
block.size = CGSizeMake(width, width);
[self addChild:block];
}
}
[self addChild:player];
}
I have a feeling that it's something to do with the self addChild:block line however I can't figure out a solution. If you need any more information I'll post it under here (just ask for it)
Thanks for your help
EDIT 1:
generateBoard method:
- (void)generateBoard
{
int rnd = 2;
int from = rnd;
int to = 0;
Row *row = [defaultRows objectAtIndex:rnd];
[boardRows replaceObjectAtIndex:0 withObject:row];
for (int i = 2; i < boardRows.count; i++)
{
rnd = arc4random() % [AppDelegate numberOfColumns];
to = rnd;
Row *rowThis = [defaultRows objectAtIndex:rnd];
Row *rowBelow = [[Row alloc] initWithSize:CGSizeMake(self.frame.size.width, self.frame.size.height) need:kNeed];
[rowBelow generateWithPoint:from toPoint:to];
[boardRows replaceObjectAtIndex:i withObject:rowThis];
[boardRows replaceObjectAtIndex:i-1 withObject:rowBelow];
to = from;
from = rnd;
// to make it add 2
i++;
}
}
EDIT 2:
After adding in the Exception Breakpoint, it revealed that the line causing the issue is the self addChild:block line

The answer to this was really simple, basically I had some pre configured blocks to make the generation easier, however in doing this, calling self addChild:block was actually trying to add the same block (with the same memory address) into 2 places at once, and therefore was crashing the app.
I just added a duplicate function to my Block class and started to implement that rather than calling the block directly.

Related

Crash issue related to [UITextField _textNeedsSanitizing:]

My ios8 application is crash giving following logs
Incident Identifier:
CrashReporter Key:
Hardware Model: iPhone7,2
Process: APP Beta [3203]
Path: /private/var/mobile/Containers/Bundle/Application/B471AC73-68B1-425B-/APP Beta.app/APP Beta
Identifier: com.product.APP
Version: 2.0.34
Code Type: ARM-64
Parent Process: launchd [1]
Date/Time: 2015-07-20T22:21:19Z
OS Version: iPhone OS 8.4 (1243)
Report Version: 104
Exception Type: SIGABRT
Exception Codes: #0 at 0x196d23270
Crashed Thread: 0
Application Specific Information:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM rangeOfCharacterFromSet:]: unrecognized selector sent to instance 0x17045d2e0'
Last Exception Backtrace:
0 CoreFoundation 0x00000001848942d8 <redacted> + 132
1 libobjc.A.dylib 0x00000001965600e4 objc_exception_throw + 60
2 CoreFoundation 0x000000018489b3a4 <redacted> + 0
3 CoreFoundation 0x0000000184898154 <redacted> + 928
4 CoreFoundation 0x000000018479accc _CF_forwarding_prep_0 + 92
5 UIKit 0x0000000189a60a24 -[UITextField _textNeedsSanitizing:] + 148
6 UIKit 0x000000018934a114 -[UITextField setText:] + 56
7 APP Beta 0x00000001001c13b4 -[APPEditCardInformation initWithFrame:] + 1384
8 APP Beta 0x0000000100182a60 -[APPEditViewController drawPrimaryView] + 568
9 APP Beta 0x0000000100181234 -[APPEditViewController viewDidLoad] + 432
10 UIKit 0x000000018930cc18 -[UIViewController loadViewIfRequired] + 692
11 UIKit 0x000000018930c928 -[UIViewController view] + 32
12 UIKit 0x00000001894af1f0 -[UINavigationController _startCustomTransition:] + 712
13 UIKit 0x00000001893c1e84 -[UINavigationController _startDeferredTransitionIfNeeded:] + 468
14 UIKit 0x00000001893c1c50 -[UINavigationController __viewWillLayoutSubviews] + 56
15 UIKit 0x00000001893c1bd0 -[UILayoutContainerView layoutSubviews] + 200
16 UIKit 0x00000001893096f4 -[UIView layoutSublayersOfLayer:] + 580
17 QuartzCore 0x0000000188c45db8 -[CALayer layoutSublayers] + 152
18 QuartzCore 0x0000000188c40820 <redacted> + 320
19 QuartzCore 0x0000000188c406c4 <redacted> + 32
20 QuartzCore 0x0000000188c3fe58 <redacted> + 276
21 QuartzCore 0x0000000188c3fbd8 <redacted> + 528
22 QuartzCore 0x0000000188c39300 <redacted> + 80
23 CoreFoundation 0x000000018484c2a4 <redacted> + 32
24 CoreFoundation 0x0000000184849230 <redacted> + 360
25 CoreFoundation 0x0000000184849610 <redacted> + 836
26 CoreFoundation 0x00000001847752d4 CFRunLoopRunSpecific + 396
27 GraphicsServices 0x000000018e1cb6fc GSEventRunModal + 168
28 UIKit 0x0000000189372f40 UIApplicationMain + 1488
29 APP Beta 0x0000000100190bf4 -[NSInvocation mp_returnValue] + 23644
30 libdyld.dylib 0x0000000196c0aa08 <redacted> + 4
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x0000000196d23270 __pthread_kill + 8
1 libsystem_c.dylib 0x0000000196c9ab18 abort + 112
2 APP Beta 0x000000010067b9e0 -[FlurryPLCrashReporter generateLiveReportWithThread:] + 0
3 CoreFoundation 0x0000000184894698 <redacted> + 692
4 libobjc.A.dylib 0x00000001965603b4 <redacted> + 116
5 libc++abi.dylib 0x0000000195d49bb4 <redacted> + 16
6 libc++abi.dylib 0x0000000195d49478 <redacted> + 0
7 libobjc.A.dylib 0x0000000196560204 <redacted> + 0
8 CoreFoundation 0x000000018489b3a4 <redacted> + 0
9 CoreFoundation 0x0000000184898154 <redacted> + 928
10 CoreFoundation 0x000000018479accc _CF_forwarding_prep_0 + 92
11 UIKit 0x0000000189a60a24 -[UITextField _textNeedsSanitizing:] + 148
12 UIKit 0x000000018934a114 -[UITextField setText:] + 56
13 APP Beta 0x00000001001c13b4 -[APPEditCardInformation initWithFrame:] + 1384
14 APP Beta 0x0000000100182a60 -[APPEditViewController drawPrimaryView] + 568
15 APP Beta 0x0000000100181234 -[APPEditViewController viewDidLoad] + 432
16 UIKit 0x000000018930cc18 -[UIViewController loadViewIfRequired] + 692
17 UIKit 0x000000018930c928 -[UIViewController view] + 32
18 UIKit 0x00000001894af1f0 -[UINavigationController _startCustomTransition:] + 712
19 UIKit 0x00000001893c1e84 -[UINavigationController _startDeferredTransitionIfNeeded:] + 468
20 UIKit 0x00000001893c1c50 -[UINavigationController __viewWillLayoutSubviews] + 56
21 UIKit 0x00000001893c1bd0 -[UILayoutContainerView layoutSubviews] + 200
22 UIKit 0x00000001893096f4 -[UIView layoutSublayersOfLayer:] + 580
23 QuartzCore 0x0000000188c45db8 -[CALayer layoutSublayers] + 152
24 QuartzCore 0x0000000188c40820 <redacted> + 320
25 QuartzCore 0x0000000188c406c4 <redacted> + 32
26 QuartzCore 0x0000000188c3fe58 <redacted> + 276
27 QuartzCore 0x0000000188c3fbd8 <redacted> + 528
28 QuartzCore 0x0000000188c39300 <redacted> + 80
29 CoreFoundation 0x000000018484c2a4 <redacted> + 32
30 CoreFoundation 0x0000000184849230 <redacted> + 360
31 CoreFoundation 0x0000000184849610 <redacted> + 836
32 CoreFoundation 0x00000001847752d4 CFRunLoopRunSpecific + 396
33 GraphicsServices 0x000000018e1cb6fc GSEventRunModal + 168
34 UIKit 0x0000000189372f40 UIApplicationMain + 1488
35 APP Beta 0x0000000100190bf4 -[NSInvocation mp_returnValue] + 23644
36 libdyld.dylib 0x0000000196c0aa08 <redacted> + 4
Does anybody has any idea regarding this issue?
This is the function which I am calling in viewWillAppear
- (void)updateEditView {
if (IS_IPAD) {
float height = 0;
float width = 0;
if (INTERFACE_IS_PHONE || [[UIScreen mainScreen] bounds].size.height == 480) {
height = HEIGHT;
width = WIDTH;
}
else {
if( [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeRight) {
if (IS_OS_8_OR_LATER) {
height = HEIGHT;
width = WIDTH;
}
else {
height = WIDTH;
width = HEIGHT;
}
}
else {
height = HEIGHT;
width = WIDTH;
}
}
navigationBar.frame = CGRectMake(navigationBar.frame.origin.x, navigationBar.frame.origin.y, width, navigationBar.frame.size.height);
titleLabel.frame = CGRectMake(50, 21, width - 100, 45);
if (innerView == 1) {
editAddress.frame = CGRectMake(0, 0, width, height);
editAddress.userFullName.frame = CGRectMake(editAddress.userFullName.frame.origin.x, editAddress.userFullName.frame.origin.y, width - (2*editAddress.userFullName.frame.origin.x), editAddress.userFullName.frame.size.height);
editAddress.streetAddress.frame = CGRectMake(editAddress.streetAddress.frame.origin.x, editAddress.streetAddress.frame.origin.y, width - (2*editAddress.streetAddress.frame.origin.x), editAddress.streetAddress.frame.size.height);
editAddress.zipCode.frame = CGRectMake(editAddress.zipCode.frame.origin.x, editAddress.zipCode.frame.origin.y, width - (2*editAddress.zipCode.frame.origin.x), editAddress.zipCode.frame.size.height);
editAddress.cityField.frame = CGRectMake(editAddress.cityField.frame.origin.x, editAddress.cityField.frame.origin.y, width/2 - (2*editAddress.cityField.frame.origin.x), editAddress.cityField.frame.size.height);
editAddress.stateField.frame = CGRectMake(width/2 + 20, editAddress.stateField.frame.origin.y, width/2 - (2*20), editAddress.stateField.frame.size.height);
editAddress.onlySeperator.frame = CGRectMake(width/2.0, 66 + 180, 1, 60);
if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeRight) {
editAddress.saveButton.frame = CGRectMake(140, editAddress.saveButton.frame.origin.y, width - 2*140, editAddress.saveButton.frame.size.height);
}
else
editAddress.saveButton.frame = CGRectMake(10, editAddress.saveButton.frame.origin.y, width - 20, editAddress.saveButton.frame.size.height);
}
else if (innerView == 2) {
editCardInfo.frame = CGRectMake(0, 0, width, height);
editCardInfo.onlySeperator.frame = CGRectMake(width/2.0, 66 + 120, 1, 60);
editCardInfo.nameOnCard.frame = CGRectMake(editCardInfo.nameOnCard.frame.origin.x, editCardInfo.nameOnCard.frame.origin.y, width - (2*editCardInfo.nameOnCard.frame.origin.x), editCardInfo.nameOnCard.frame.size.height);
editCardInfo.creditCardNumber.frame = CGRectMake(editCardInfo.creditCardNumber.frame.origin.x, editCardInfo.creditCardNumber.frame.origin.y, width - (2*editCardInfo.creditCardNumber.frame.origin.x), editCardInfo.creditCardNumber.frame.size.height);
editCardInfo.expireDate.frame = CGRectMake(editCardInfo.expireDate.frame.origin.x, editCardInfo.expireDate.frame.origin.y, width/2 - (2*editCardInfo.expireDate.frame.origin.x), editCardInfo.expireDate.frame.size.height);
editCardInfo.cvcNumber.frame = CGRectMake(width/2 + 20, editCardInfo.cvcNumber.frame.origin.y, width/2 - (2*20), editCardInfo.cvcNumber.frame.size.height);
editCardInfo.creditCardImage.frame = CGRectMake(width - 20 - 33, editCardInfo.creditCardImage.frame.origin.y, editCardInfo.creditCardImage.frame.size.width, editCardInfo.creditCardImage.frame.size.height);
if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeRight) {
editCardInfo.saveButton.frame = CGRectMake(140, editCardInfo.saveButton.frame.origin.y, width - 2*140, editCardInfo.saveButton.frame.size.height);
}
else
editCardInfo.saveButton.frame = CGRectMake(10, editCardInfo.saveButton.frame.origin.y, width - 20, editCardInfo.saveButton.frame.size.height);
}
else if (innerView == 3) {
editContactInfo.frame = CGRectMake(0, 0, width, height);
editContactInfo.emailAddressField.frame = CGRectMake(editContactInfo.emailAddressField.frame.origin.x, editContactInfo.emailAddressField.frame.origin.y, width - 2*editContactInfo.emailAddressField.frame.origin.x, editContactInfo.emailAddressField.frame.size.height);
editContactInfo.contactNumberField.frame = CGRectMake(editContactInfo.contactNumberField.frame.origin.x, editContactInfo.contactNumberField.frame.origin.y, width - 2*editContactInfo.contactNumberField.frame.origin.x, editContactInfo.contactNumberField.frame.size.height);
if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeRight) {
editContactInfo.saveButton.frame = CGRectMake(140, editContactInfo.saveButton.frame.origin.y, width - 2*140, editContactInfo.saveButton.frame.size.height);
}
else
editContactInfo.saveButton.frame = CGRectMake(10, editContactInfo.saveButton.frame.origin.y, width - 20, editContactInfo.saveButton.frame.size.height);
}
}
}
This issue is occurring when user is opening the app from background.
tl;dr it is an memory issue, the string is not valid anymore.
you can simple reproduce the stacktrace with the following steps / code:
// 1) create a property to enforce the memory issue
#property (nonatomic, assign) NSString* dumpString
now we just trick the compiler a little bit...
// 2) create an invalid "string"object, in this case, a view :)
NSDictionary* dict = #{#"key": [[UIView alloc] init]};
// 3) because objectForKey: will return an id, the runtime has no idea that it is no string
self.dumpString = [dict objectForKey:#"key"];
// 4) here is your crash, when we set the value to the textfield, the textfield tries to sanitize the string and runs into an invalid memory layout
self.textField.text = self.dumpString;

Getting values from UISliders with tags

Introduction
I've created a bunch of sliders with a loop. I now want to retrieve their values when a button is pushed. There seems to be some issue which is causing the app to crash, I'm not really sure what's going wrong
Code
Defining slider tags
slider1.tag = count;
count += 1;
[subView addSubview:slider1];
Retrieving slider values
-(void) build:(id)sender {
for (int i = 0; i < count; i++){
UISlider *Slider = (UISlider*)[self.view viewWithTag:i];
NSLog(#"%f",Slider.value);
}
}
Logs
I'm guessing this means that the slider isn't found, but why is this happening?
2014-07-25 17:18:49.911 App1.0[5155:a0b] -[UIView value]: unrecognized
selector sent to instance 0x109a44f00
2014-07-25 17:18:49.913 App1.0[5155:a0b] * Terminating app due to
uncaught exception 'NSInvalidArgumentException', reason: '-[UIView
value]: unrecognized selector sent to instance 0x109a44f00'
* First throw call stack: ( 0 CoreFoundation 0x0000000101ae8795 exceptionPreprocess + 165 1 libobjc.A.dylib
0x000000010184b991 objc_exception_throw + 43 2 CoreFoundation
0x0000000101b79bad -[NSObject(NSObject) doesNotRecognizeSelector:] +
205 3 CoreFoundation 0x0000000101ada09d
___forwarding_ + 973 4 CoreFoundation 0x0000000101ad9c48 _CF_forwarding_prep_0 + 120 5 Dream1.0
0x0000000100001d8d -[TemplateViewController build:] + 173 6 UIKit
0x00000001004af096 -[UIApplication sendAction:to:from:forEvent:] + 80
7 UIKit 0x00000001004af044
-[UIApplication sendAction:toTarget:fromSender:forEvent:] + 17 8 UIKit 0x0000000100583450 -[UIControl
_sendActionsForEvents:withEvent:] + 203 9 UIKit 0x00000001005829c0 -[UIControl touchesEnded:withEvent:] + 530 10
UIKit 0x00000001007b3c3d
_UIGestureRecognizerUpdate + 5149 11 UIKit 0x00000001004e3925 -[UIWindow _sendGesturesForEvent:] + 928 12 UIKit
0x00000001004e45e5 -[UIWindow sendEvent:] + 910 13 UIKit
0x00000001004bdfa2 -[UIApplication sendEvent:] + 211 14 UIKit
0x00000001004abd7f _UIApplicationHandleEventQueue + 9549 15
CoreFoundation 0x0000000101a77ec1
CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 17 16 CoreFoundation 0x0000000101a77792
__CFRunLoopDoSources0 + 242 17 CoreFoundation 0x0000000101a9361f __CFRunLoopRun + 767 18 CoreFoundation
0x0000000101a92f33 CFRunLoopRunSpecific + 467 19 GraphicsServices
0x000000010311b3a0 GSEventRunModal + 161 20 UIKit
0x00000001004ae043 UIApplicationMain + 1010 21 Dream1.0
0x0000000100005903 main + 115 22 libdyld.dylib
0x0000000103dc37e1 start + 0 ) libc++abi.dylib: terminating with
uncaught exception of type NSException (lldb)
This is because your viewWithTag: doesn't return UISlider every time.
In first loop iteration:
for (int i = 0; i < count; i++){
i is equal 0 and 0 is a default value, so every UIView subclass (in the view controller) you haven't change the tag property has that value set to 0, for example the button you press.
One of the solution is to set up your UISlider tag from 1 not 0 and you should enumerate from 1 when you retrieve the slider, you should do also safety chack to make sure you have UISlider:
// First value of count should be 1, not 0:
// You can set it in init method or before loop count = 1;
slider1.tag = count;
count += 1;
[subView addSubview:slider1];
-(void) build:(id)sender {
for (int i = 1; i <= count; i++){
UIView *v = [self.view viewWithTag:i];
if ([v isKindOfClass:[UISlider class]) {
UISlider *Slider = (UISlider*)v;
NSLog(#"%f",Slider.value);
}
}
}

How to add an SKNode to an SKScene

When I enter this line in initWithSize:Size
[self addChild:world];
I retrive an error Thread 1:signal SIGABRT
world is an SKNode
The children that should be in world are also SKNode's
What am I doing wrong here as when I add the SKNode to the scene I retrieve an error
initWithSize:Size Method:
-(id)initWithSize:(CGSize)size{
if (self = [super initWithSize:size]){
//self.size = CGSizeMake(2048, 1048);
self.backgroundColor = [SKColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
_character = [self createCharacter];
[self addChild:_character];
[self addChild:world];
[self createChunks];
[world addChild:_character];
NSLog(#"Children in world: %#",[world children]);
}
return self;
}
createChunks: Method:
-(void)createChunks{
ProceduralMapGeneration *procedure = [[ProceduralMapGeneration alloc]init];
[procedure allocArrays];
_chunkOne = [procedure createChunk];
_chunkOne.position = CGPointMake(self.scene.size.width/2, self.scene.size.height/2);
[world addChild:_chunkOne];
_chunkTwo = [procedure createChunk];
_chunkTwo.position = CGPointMake(400,200);
[world addChild:_chunkTwo];
}
create chunks adds the chunks to world
world is created here
#implementation MainGame{
SKNode *world;
SKSpriteNode *_character;
SKNode *_chunkOne;
SKNode *_chunkTwo;
ProceduralMapGeneration *categoryBitManager;
}
Stack Trace
*** First throw call stack:
(
0 CoreFoundation 0x019161e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x016958e5 objc_exception_throw + 44
2 CoreFoundation 0x01915fbb +[NSException raise:format:] + 139
3 SpriteKit 0x0117cfca -[SKNode addChild:] + 175
4 Giraffe Rampage 0x0000289d -[MainGame initWithSize:] + 413
5 SpriteKit 0x0115ca09 +[SKScene sceneWithSize:] + 104
6 Giraffe Rampage 0x0000555d -[MainMenu touchesBegan:withEvent:] + 429
7 SpriteKit 0x0116e2bf -[SKView touchesBegan:withEvent:] + 824
8 UIKit 0x00274c0b -[UIWindow _sendTouchesForEvent:] + 386
9 UIKit 0x002759d1 -[UIWindow sendEvent:] + 1117
10 UIKit 0x002475f2 -[UIApplication sendEvent:] + 242
11 UIKit 0x00231353 _UIApplicationHandleEventQueue + 11455
12 CoreFoundation 0x0189f77f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
13 CoreFoundation 0x0189f10b __CFRunLoopDoSources0 + 235
14 CoreFoundation 0x018bc1ae __CFRunLoopRun + 910
15 CoreFoundation 0x018bb9d3 CFRunLoopRunSpecific + 467
16 CoreFoundation 0x018bb7eb CFRunLoopRunInMode + 123
17 GraphicsServices 0x0390a5ee GSEventRunModal + 192
18 GraphicsServices 0x0390a42b GSEventRun + 104
19 UIKit 0x00233f9b UIApplicationMain + 1225
20 Giraffe Rampage 0x00005e6d main + 141
21 libdyld.dylib 0x01f5d701 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
[self addChild:_character];
...
[world addChild:_character];
You added _character twice.

Crash in drawRect - what causes it?

Some of my users are getting this crash.
As far as I can tell, it's somehow connected to the -drawRect: method of my subclassed NSTextView, but I can't see what might cause it, and stress testing has failed to shake out the bug.
Code for drawRect
- (NSRange)visibleRangeOfTextView:(NSRect) rect {
NSLayoutManager *layoutManager = [self
layoutManager];
NSTextContainer *textContainer = [self
textContainer];
NSRange glyphRange, characterRange;
// first transform to text container coordinates
NSPoint containerOrigin = [self textContainerOrigin];
rect.origin.x -= containerOrigin.x;
rect.origin.y -= containerOrigin.y;
// next, compute glyph range
glyphRange = [layoutManager glyphRangeForBoundingRect:rect inTextContainer:textContainer];
// finally, compute character range
characterRange = [layoutManager characterRangeForGlyphRange:glyphRange actualGlyphRange:NULL];
return characterRange;
}
- (NSRect)rectForCharacterRange:(NSRange)charRange
{
NSRect rect = [self
firstRectForCharacterRange:charRange];
rect.origin = [[self window]
convertScreenToBase:rect.origin];
rect = [self convertRect:rect fromView:nil];
if (!rect.size.width) rect.size.width = 6.0;
return rect;
}
- (void)drawRect:(NSRect)dirtyRect
{
[super drawRect:dirtyRect];
NSLog(#"Marking it");
NSMutableArray *arr = [[NSMutableArray alloc] init];
NSRange visible = [self visibleRangeOfTextView:dirtyRect];
NSRange last = NSMakeRange(visible.location, 0); while (true) {
NSRange error = [appController rangeOfMisspelledWordInString:self.string onlyInRange:visible startingAt:last.location + last.length];
last = error;
if (error.location == NSNotFound) {
break;
}
[arr addObject:[NSValue valueWithRange:error]];
}
NSLog(#"Spellchecked");
[[NSColor redColor] setStroke];
CGFloat dash[] = {2.0f, 2.0f} ;
// Make the text ranges and mark them
for (NSValue *val in arr) {
NSRange range = [val rangeValue];
NSRect rectInTextView = [self rectForCharacterRange:range];
NSRect toDraw = rectInTextView;
NSBezierPath* aPath = [NSBezierPath bezierPath];
[aPath setLineDash:dash count:2 phase:0];
NSPoint lineStart = toDraw.origin;
lineStart.y += toDraw.size.height;
NSPoint lineEnd = lineStart;
lineEnd.x += toDraw.size.width;
[aPath moveToPoint:lineStart];
[aPath lineToPoint:lineEnd];
[aPath stroke];
};
NSLog(#"Done");
}
Stack trace:
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Application Specific Information:
objc[5751]: garbage collection is ON
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSConcreteTextStorage attribute:atIndex:longestEffectiveRange:inRange:]: Range or index out of bounds'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff91387fc6 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff8d4d7d5e objc_exception_throw + 43
2 CoreFoundation 0x00007fff91387dfa +[NSException raise:format:arguments:] + 106
3 CoreFoundation 0x00007fff91387d84 +[NSException raise:format:] + 116
4 AppKit 0x00000001005d842c -[NSConcreteTextStorage attribute:atIndex:longestEffectiveRange:inRange:] + 131
5 AppKit 0x00000001006288ec -[NSLayoutManager(NSPrivate) _drawBackgroundForGlyphRange:atPoint:parameters:] + 910
6 AppKit 0x00000001006277a2 -[NSTextView drawRect:] + 1913
7 Skrivest√∏tte 0x000000010000b56c Skrivest√∏tte + 46444
8 AppKit 0x0000000100626e66 -[NSTextView _drawRect:clip:] + 2545
9 AppKit 0x00000001004a985d -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 3020
10 AppKit 0x00000001004aa34e -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 5821
11 AppKit 0x00000001004aa34e -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 5821
12 AppKit 0x00000001004a39af -[NSView _displayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:] + 4755
13 AppKit 0x000000010049c395 -[NSView displayIfNeeded] + 1528
14 AppKit 0x00000001004a1592 -[NSClipView _immediateScrollToPoint:] + 6533
15 AppKit 0x000000010049fb75 -[NSClipView scrollToPoint:] + 239
16 AppKit 0x000000010058f637 -[NSScrollView scrollClipView:toPoint:] + 266
17 AppKit 0x000000010058f3da -[NSClipView _scrollTo:animateScroll:flashScrollerKnobs:] + 1497
18 AppKit 0x00000001005923b7 -[NSClipView _scrollTo:animate:] + 27
19 AppKit 0x0000000100bcd5a2 __-[NSScrollView _snapRubberBand]_block_invoke_2 + 1536
20 AppKit 0x0000000100b3fc4e ____NSPeriodicInvokerScheduled_block_invoke_2 + 53
21 libdispatch.dylib 0x00007fff907b98ba _dispatch_call_block_and_release + 18
22 libdispatch.dylib 0x00007fff907bbc07 _dispatch_after_timer_callback + 16
23 libdispatch.dylib 0x00007fff907be2b6 _dispatch_source_invoke + 635
24 libdispatch.dylib 0x00007fff907baf77 _dispatch_queue_invoke + 71
25 libdispatch.dylib 0x00007fff907bb6f7 _dispatch_main_queue_callback_4CF + 257
26 CoreFoundation 0x00007fff9131d06c __CFRunLoopRun + 1724
27 CoreFoundation 0x00007fff9131c676 CFRunLoopRunSpecific + 230
28 HIToolbox 0x00007fff93ab831f RunCurrentEventLoopInMode + 277
29 HIToolbox 0x00007fff93abf5c9 ReceiveNextEventCommon + 355
30 HIToolbox 0x00007fff93abf456 BlockUntilNextEventMatchingListInMode + 62
31 AppKit 0x000000010045ff5d _DPSNextEvent + 659
32 AppKit 0x000000010045f861 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 135
33 AppKit 0x000000010045c19d -[NSApplication run] + 470
34 AppKit 0x00000001006dab88 NSApplicationMain + 867
35 Skrivest√∏tte 0x0000000100001020 Skrivest√∏tte + 4128
36 ??? 0x0000000000000002 0x0 + 2
)
* Terminating app due to uncaught exception 'NSRangeException', reason: '*
[NSConcreteTextStorage attribute:atIndex:longestEffectiveRange:inRange:]: Range or index out of bounds'
It is clearly a NSRange exception, as O' y said
I think you need add assert function to check the "range"
NSRange range = [val rangeValue];
make sure range will not be NSNotFound.

SIGABRT while adding objects to an NSMutableArray

I have a method which returns an NSArray with points to be plotted. Following is the code for my method.
- (NSArray *)pointsToPlot:(GraphView *)requester
{
NSMutableArray *points = [[NSSet alloc] init];
CGPoint midPoint;
midPoint.x = self.graph.bounds.origin.x + self.graph.bounds.size.width / 2;
midPoint.y = self.graph.bounds.origin.y + self.graph.bounds.size.height / 2;
//Find points to plot
NSValue *point1 = [NSValue valueWithCGPoint:CGPointMake(midPoint.x - 10, midPoint.y)];
NSValue *point2 = [NSValue valueWithCGPoint:CGPointMake(midPoint.x, midPoint.y - 10)];
NSValue *point3 = [NSValue valueWithCGPoint:CGPointMake(midPoint.x + 10, midPoint.y)];
[points addObject:point1];
[points addObject:point2];
[points addObject:point3];
[points autorelease];
return points;
}
I am getting SIGABRT as soon as I add point1 to the points array.
Following is the stack trace obtained:
2011-10-27 10:43:36.939 Graphing Calculator[7056:207] -[__NSSet0 addObject:]: unrecognized selector sent to instance 0x4b57900
2011-10-27 10:43:36.943 Graphing Calculator[7056:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSSet0 addObject:]: unrecognized selector sent to instance 0x4b57900'
*** Call stack at first throw:
(
0 CoreFoundation 0x00dc95a9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x00f1d313 objc_exception_throw + 44
2 CoreFoundation 0x00dcb0bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x00d3a966 ___forwarding___ + 966
4 CoreFoundation 0x00d3a522 _CF_forwarding_prep_0 + 50
5 Graphing Calculator 0x000073cd -[GraphViewController pointsToPlot:] + 1037
6 Graphing Calculator 0x00006895 -[GraphView drawRect:] + 965
7 UIKit 0x00053187 -[UIView(CALayerDelegate) drawLayer:inContext:] + 426
8 QuartzCore 0x016b3b5e -[CALayer drawInContext:] + 143
9 QuartzCore 0x016bfe47 _ZL16backing_callbackP9CGContextPv + 85
10 QuartzCore 0x0160d1f7 CABackingStoreUpdate + 2246
11 QuartzCore 0x016bfd24 -[CALayer _display] + 1085
12 QuartzCore 0x016b627d CALayerDisplayIfNeeded + 231
13 QuartzCore 0x0165b0c3 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 325
14 QuartzCore 0x0165c294 _ZN2CA11Transaction6commitEv + 292
15 QuartzCore 0x0165c46d _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 99
16 CoreFoundation 0x00daa89b __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 27
17 CoreFoundation 0x00d3f6e7 __CFRunLoopDoObservers + 295
18 CoreFoundation 0x00d081d7 __CFRunLoopRun + 1575
19 CoreFoundation 0x00d07840 CFRunLoopRunSpecific + 208
20 CoreFoundation 0x00d07761 CFRunLoopRunInMode + 97
21 GraphicsServices 0x010011c4 GSEventRunModal + 217
22 GraphicsServices 0x01001289 GSEventRun + 115
23 UIKit 0x00029c93 UIApplicationMain + 1160
24 Graphing Calculator 0x000021d9 main + 121
25 Graphing Calculator 0x00002155 start + 53
)
terminate called after throwing an instance of 'NSException'
Could someone please explain me what am I doing wrong here?
Change
NSMutableArray *points = [[NSSet alloc] init];
to
NSMutableArray *points = [[NSMutableArray alloc] init];
You are creating and initializing an NSSet and storing it to a reference for NSMutableArray.
Change the following line:
NSMutableArray *points = [[NSSet alloc] init];
To this line:
NSMutableArray *points = [[NSMutableArray alloc] initWithCapacity:3];