Xcode Bad Access Error when calling method - xcode

I have a ViewController and in the viewDidLoad Method i initialize a GLKView.
After the GLKView is initialized i try to call a method of that View:
- (void)viewDidLoad
{
[super viewDidLoad];
self.myController = [[MyController alloc] init];
self.myController.parameter1 = #"BLA";
[self.myController initTargets];
}
My initTargets Method is not really amazing. It actually does not more
than this:
- (void) initTargets
{
MyTarget *targetOne = [[MyTarget alloc] initWithParameter:self.parameter1];
[self.targets addObject:targetOne];
}
When i try to call the initTargets Method like described above i get the
following error:
Thread 1: EXC_BAD_ACCESS (code=1, address = 0xe80000000)
I never had such a Problem with just calling methods and i dont know what
this error is trying to say me.

Go to Breakpoints pane in xCode, and click the plus sign from the lower left corner. By default, xCode adds an "All exceptions" breakpoint, which means it will stop at any exception, before the actual crash. This is how I debug all "Bad access" exceptions, except for the ones in blocks.

Your accessing an object or pointer that doesn't exist / hasn't been allocated yet. Or has already been destroyed.
So either MyTarget isn't being allocated properly or self.targets isn't.
What is self.targets ? Does that need to be allocated first ?
Also, you have self.paramter1, shouldnt it be self.myController.parameter1 ?

Related

Drag and drop files into NSOutlineView

I'm trying to implement simple drag and drop operation into NSOutlineView Based on Apple's example - https://developer.apple.com/library/mac/samplecode/SourceView/Introduction/Intro.html
All seems to be ok, but finally when I drop some files from Finder I get error:
[<ChildNode 0x60800005a280> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key description.') was raised during a dragging session
Here is my test project: https://www.dropbox.com/s/1mgcg2dysvs292u/SimpleDrag.zip?dl=0
What I exactly need in my app: allow user to drag and drop multiple files and folder into some tree list and then display them to user. Also save all this this into some file, so it can be loaded again with all user dragged files and folders.
A final result I want to have like this:
The description property of NSObject is read-only, and is generally set by providing a getter in the implementation file:
- (NSString *)description {
return [self urlString]; // Using urlString solely for demo purposes.
}
You can't set it, either via key-value coding or by direct assignment:
self.description = [self urlString]; // Xcode error: 'Assignment to readonly property'
[self setValue:[self urlString] forKey:#"description"];
In -[ChildNode copyWithZone:] an attempt is made to do the latter of the two, and that's what causes the warning to be logged to the console.
// -------------------------------------------------------------------------------
// copyWithZone:zone
// -------------------------------------------------------------------------------
- (id)copyWithZone:(NSZone *)zone
{
id newNode = [[[self class] allocWithZone:zone] init];
// One of the keys in mutableKeys is 'description'...
// ...but it's readonly! (it's defined in the NSObject protocol)
for (NSString *key in [self mutableKeys])
{
[newNode setValue:[self valueForKey:key] forKey:key];
}
return newNode;
}
This begs the question why do you get the warning in your app, and not in the sample app? From what I can tell no ChildNode instance is ever sent a copyWithZone: message in the sample app, whereas this does happen in your app, immediately after the drop. Of course there's a second question here as well: why do Apple explicitly include the description key-path when it can't be set this way? - unfortunately I can't help you with that.
A really handy way of trying to trap errors that don't actually cause exceptions is to add an All Exceptions breakpoint. If you do this in your sample app you'll see that the app freezes at the line that's causing the problem, giving you a better chance of figuring out the issue.

What issues could arise when using GCD dispatchAfter() in this use case

I'm going through a book on OS X programing as a refresher and have a document app set up with an array controller, tableView etc. The chapter calls for implementing undo support by hand using NSInvocation. In the chapter, they call for adding a create employee method and manually, adding outlets to the NSArrayController, and connecting my add button to the new method instead of the array controller.
Instead I did this with my method for inserting new objects:
-(void)insertObject:(Person *)object inEmployeesAtIndex:(NSUInteger)index {
NSUndoManager* undoManager = [self undoManager];
[[undoManager prepareWithInvocationTarget:self]removeObjectFromEmployeesAtIndex:index];
if (![undoManager isUndoing]) {
[undoManager setActionName:#"Add Person"];
}
[self startObservingPerson:object];
[[self employees]insertObject:object atIndex:index];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// Wait then start editing
[[self tableView]editColumn:0 row:index withEvent:nil select:YES];
});
}
This works ok (looks a bit silly), but I was wondering the what issues could arise from this. I've done this elsewhere in order to execute code after an animation finished (couldn't figure out a better way).
Thanks in advance.
Why are you delaying the invocation of -editColumn:row:withEvent:select:?
Anyway, the risks are that something else will be done between the end of this -insertObject:... method and when the dispatched task executes. Perhaps something that will change the contents of the table view such that index no longer refers to the just-added employee.

UITextField - message sent to deallocated instance "UIKBStringWideAttributeValueForKey:"

After enabling Zombie Objects I am able to see the following error when I try to edit a UITextField (textLvl):
2013-01-13 13:27:10.509 testob[18418:907] *** -[NSConcreteMutableAttributedString
_UIKBStringWideAttributeValueForKey:]: message sent to deallocated instance 0x2066a1f0
I have posted the portion of code that is causing the issue below, it seems to specifically be the "textField.text = self.storeText;" part - as when I comment this out the problem goes away.
You may be able to tell I am not the most experienced iOS dev, why would my UITextView deallocate after I've set the text? Help please!
Also, I've never heard of "_UIKBStringWideAttributeValueForKey" before - any ideas?
Thanks all!
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
NSLog(#"Text began editing");
self.storeText = textField.text;
textField.text = #"";
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
if (textField == textLvl){
if ([textField.text isEqualToString:#""]){
textField.text = self.storeText;
NSLog(#"No Text");
}
self.conv = [textField.text intValue];
if (self.conv >= 101){
textField.text = #"100";
UIAlertView *successAlert = [[UIAlertView alloc] initWithTitle:#"Oh no!" message:#"Can't be higher than 100." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[successAlert show]; }
}}
This might be a bug internal to the framework. I suggest you add - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField and set the textfield text to nil and then reset the textfield text.
I think the real answer here is that you're dealing with a UITextField that has been set to handle NSAttributedString rather than NSString. You'll notice if you're dealing with UITextField defined in a .xib, it's top property option is now "Text" with options Plain or Attributed.
If your text field was switched to attributed, you'll find this error happening if you continue to deal with the text field as if it were Plain.
My textfield was in a xib file and it's delegate was hooked up to the files owner. This was causing the crash for me, because the file's owner was NSObject.
I actually wanted to hook up the delegate to the cell, and not files owner.
Use instruments so see the retains/releases:
If you need to see where retains, releases and autoreleases occur for an object use instruments:
Run in instruments, in Allocations set "Record reference counts" on on (you have to stop recording to set the option). Cause the picker to run, stop recording, search for there ivar (datePickerView), drill down and you will be able to see where all retains, releases and autoreleases occurred.

Iphone app wont run after upgrading to iOS 4.2

After installing Xcode 3.2.5 iOS 4.2 an app that was perfectly working stopped working. I have seen that this has happened to others but cant understand how to solve it.
My questions are:
1. How can I know where it is crashing?
2. What can I do to better debug and pinpoint the problem.
Here is the call stack.
Tommy thanks for the answer. I have build and run and suggested but when it crashes it does not shows where it crashed. Also I added a breakpoint inside the method but it does not stops there. Any further ideas? Here is the code snippet.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
ApplicationData *appdata = [ApplicationData sharedInstance];
if(appdata.currentCategoryIndex >= 0) {
Category *category = [appdata.categoryList objectAtIndex:appdata.currentCategoryIndex];
if(category.records) {
[lab_norecords setHidden:YES];
} else {
[lab_norecords setHidden:NO];
return 0;
}
return [category.records count];
}
return 0;
}
Now I am getting this error:
I believe the source of the problem is here in the same subCategoryView:
- (id)init {
if([[NSBundle mainBundle] loadNibNamed:#"SubCategoryView" owner:self options:nil]) {
//if(self = [super initWit])
cellowner = [[TableCellOwner alloc] init];
[listTableView setBackgroundColor:[UIColor clearColor]];
[listTableView setSeparatorColor:[UIColor whiteColor]];
[listTableView initialize];
}
return self;
}
From the trace you've got, check out the second column. The most recent thing in your application was a call to SubCategoryView numberOfSectionsInTableView:, in the fourth row (the one numbered '3'). The triggered exception was NSRangeException, where you attempted to retrieved object 4294967295 from an array with 22 objects in it. 4294967295 is how -1 looks if you cast a signed 32bit number to an unsigned number, so for some reason you're doing something like:
NSInteger variable = -1;
[array objectAtIndex:variable];
Somewhere within SubCategoryView's numberOfSectionsInTableView. Best immediate guess: some change between 4.1 and 4.2 is causing whatever method you use to populate the table to come up with the wrong results.
To advance from here, make sure you're doing a debug build and launch with command+y (or go to Build, Build and Run - Breakpoints On). When your program crashes this time the debugging window should appear, showing you exactly the line your program throws an exception at and allowing you to inspect the state of all your program variables at that point. The debugger will also allow you to place breakpoints, step through your program one line at a time and all the other usual things.

How to subclass AtlasSpriteManager in Cocos2d?

I need to create some compound sprites that will all move and rotate together. Since it's possible to change the position and rotation of an AtlasSpriteManager I've been trying to subclass so I can create a bunch of shortcuts like
CompoundSprite *cSprite = [CompoundSprite spriteManagerWithFile:#"sprites.png"];
[cSprite makeComplexSprite];
internally, it looks a little like this
-(void)makeComplexSprite
{
AtlasSprite *sp1 = [[AtlasSprite spriteWithRect:CGRectMake(0, 0, 64, 64)
spriteManager:self] retain];
AtlasSprite *sp2 = [[AtlasSprite spriteWithRect:CGRectMake(0, 0, 64, 64)
spriteManager:self] retain];
[self addChild:sp1];
[self addChild:sp2];
[sp1 setPosition:CGPointMake(0,0)];
[sp2 setPosition:CGPointMake(64,0)];
}
However, when I run the applications, It crashes with the following exception
Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '*** -[AtlasSpriteManager makeComplexSprite]: unrecognized selector sent to
instance 0x107e1c0
Also, if I remove all the code inside 'MakeComplexSprite' and make it do nothing, I also get the same problem.
It's looking like AtlasSpriteManager just doesn't like to be sub classed. Is this the case? If so, why, and how could I work around it?
UPDATE:
I've found a workaround, by creating an NSObject that contains an atlasSpriteManager. It does the trick, but I would still like to subclass AtlasSpriteManager if possible. I appear to be implementing this exaclty as you describe. I'm creating an instance like this
CompoundSprite *cSprite = [CompoundSprite spriteManagerWithFile:#"file.png"];
[cSprite makeBox];
which... now I think about it, means that cSprite is still an AtlasSpriteManager since that's what is being returned. hmmmm. Ho do I change that?
Implement your own spriteManagerWithFile: or compoundSpriteWithFile: in CompoundSprite, which will return an instance of CompoundSprite.
Edit:
Or, you can do something like
[[ComplexSprite alloc] makeComplexSprite];
But then you need to do the 'spriteManagerWithFile:' part also. Like:
-(id)makeComplexSpriteWithFile:(NSString*)file
{
if (! (self = [super initWithSpriteManager:..capacity:..]))
return nil;
// do your ComplexSprite specific initializing here..
return self;
}
The runtime error you are seeing indicates that your program has tried to send the makeComplexSprite message to an object, but no such method has been defined for that object.
You appear to be sending the makeComplexSprite message to an instance of AtlasSpriteManager instead of an instance of your custom CompoundSprite class. Your example code looks correct, so how are you doing the subclassing? It should look something like this:
CompoundSprite.h:
#interface CompoundSprite : AtlasSpriteManager
{
}
- (void)makeComplexSprite;
#end
CompoundSprite.m:
#interface CompoundSprite
- (void)makeComplexSprite
{
...
}
#end
If you do have the subclassing set up properly, make sure you are actually calling makeComplexSprite on an instance of CompoundSprite and not some other object by accident.
Also:
Your code sample has a memory leak. You are creating two autoreleased sprites, then retaining them (which means your class takes ownership of them), and never releasing them. Since the AddChild: method will automatically retain the objects, you can simply lose the retain calls, and everything will be good.

Resources