EXC_BAD_ACCESS on IPhone Cocos2d - iphone

I Have the following code:
-(void) changeAnimation:(NSString*)name forTime:(int) times {
if(currentAnimation != #"attack")
{
id action = [CCAnimate actionWithAnimation:[self animationByName:name]];
id repeatAction = [CCRepeat actionWithAction:action times:times];
currentAction = [self runAction:repeatAction];
lastANimation = currentAnimation;
currentAnimation = name;
}
else if(currentAction.isDone)
{
//Here is where I would change the animation
//but I commented the code for now
}
}
So when I run this and click on the button that changes the animation to "attack" (by calling [mysprite changeAnimation:#"attack" forTime:1];), I get a EXC_BAD_ACCESS error from the "currentAction.isDone" line, the next time the function is called (the joystick will call changeAnimation to try and change the animation to "run" or "idle", but I want the attack animation to finish first). Any thoughts on whyI get this? currentAction is declared in my class.
Edit: there is nothing in the rest of the class that interacts with currentAction, beside a getter. Its declaration is in the .h (CCAction* surrentAction). Do I need to initialize it? I thought the returned value from runAction would be sufficient? ANyways, when I run the debugger, it is not nil, and assigned to the correct action.
Thanks,
Dave
Edit:
I ended up creating a sequence when "attacking" that calls a function that changes the currentAnimation, so i avoided the issue. Still no idea what was happening.
Here's the answer if your interested:
Other Post

More of the class is probably needed to really answer this properly, but the EXC_BAD_ACCESS typically happens because you're accessing something that has been released and is no longer available in memory.
I'm guessing that somewhere in your class you're releasing, either explicitly, or implicitly, the "currentAction" object asynchronously - and when you're checking later, it's done & gone and you're hitting this crasher.
In general, keeping a state variable or two that you always have known values on is a good way to go, and for the "actions" that you're going through, if they're asynchronous and doing their own memory management, leave them as such and work through some state variables that you maintain and control all the memory management around. It's a pretty reasonable pattern for asynchronous callbacks, either with the classic stuff or as you move into using blocks with iOS 4.0

Related

XCode 4.5 and static (singleton) class (C++)

I'm running into a weird issue with XCode 4.5, the one supporting the new iOS6.
In most of my apps, I make a State class as a singleton accessible from everywhere for convenience, but with latest XCode, it seems like after I set any non-static pointer member to some object, right after the assignment the value is back to NULL.
Even weirder is I only see the issue if I start a new project from scratch, not if I load an older project created with an earlier version of XCode. I looked at compiler settings, and everything looks the same. The issue only appears if I test on the actual device (iPhone4 running iOS6). The simulator does not show this problem.
Here's the relevent code :
State.h
class State
{
public:
State();
~State();
static State& Get();
private:
static State * s_state;
State.mm
State* State::s_state = nil;
State& State::Get()
{
if(s_state==nil)
s_state = new State();
return *(s_state);
}
Example usage assuming State has a non-static member Object * m_object :
void SomeClass::DoSomething()
{
State::Get().SetObject( new Object() );
// this will return null with newly created XCode 4.5 projects
State::Get().GetObject();
** EDIT **
Regarding thread safety-ness, I'd like to know if the 2 cases below are considered "multi-threaded" scenarios.
I have one timer using display link for my opengl loop
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
And I have one timer responsible for updating the game logic that I init this way
timer = [NSTimer scheduledTimerWithTimeInterval:1.f/60.f target:self selector:#selector(timerUpdate) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:m_timer forMode:NSRunLoopCommonModes];
So if I call State::Get() from both these loops, is this considered a threaded scenario?
Thank you for your help.
- Marc
Your code looks okay (although it is not threadsafe). You don't post accessors, so I'll assume they are the standard type that actually get and set things.
Which means I can only guess but it's worth checking if the source of the problem is some corrupted memory that occurred earlier due to something like double delete.
Enable guard malloc and try again. You can also try valgrind.
About your edit, you should be okay as long as you are calling the addToLoop code from the main thread (you probably are calling it in some viewDidLoad or init code which is on the main thread), since both timer callbacks (timer and display link will be processed on the main loop).
Ok I found out what my issue was and thought I'd share with you all. Although it doesn't have anything to do with single/static classes, this kind of issue can be hard to debug.
In my State class, I had a member available only to a specific config :
#ifdef SOME_CONFIG
int m_someValue;
#endif
The problem in this case was that at compile time, SOME_CONFIG was actually defined, but undefined elsewhere according to target conditionals etc, causing the variable to exist on the stack but never inited/used etc. Just having the variable in the header was causing the issue (even if I didn't make any call using it.)
Hope this can help someone out there.
Thanks.

My uitableview.delegate is getting set to null. Any ideas why, or how I can figure out why?

I presume this isn't a common problem, which makes it a bit more difficult to answer. Any help is appreciated though.
I need to call this delegate a number of times in my app, and i noticed that after a number of times, the delegate starts to come back as NULL (and hence stops responding). I put an nslog everywhere the delegate gets called, so i know that at this point, it's fine:
UIImage *image = [self.delegate largeThumnailForMediaAtIndex:indexPath.row];
Then the next time this line gets called, the delegate is set to NULL. No lines around it call or set the delegate. I put an NSLog on the setDelegate method too, and that didn't get called before it changed to NULL.
Any code you might need to see, let me know. Any ideas you want me to try out, let me know about that too.
Thanks for your help.
EDIT: Bizarre, but might help to lead to a solution. I put an NSTimer scheduledTimer.. in the class which gets made the delegate, and got it to fire that once a second so I could see if it turned null at any point. The result i got, however, was that this time it didn't turn null. It returned all of the delegate methods. When i took the timer out, it goes back to returning NULL. Obviously having a timer in there is an odd workaround 'solution'. I'm hoping this rings a bell for someone and gives them a clue to where the problem might lie?
EDIT 2: I've solved this problem by, instead of using this code in my AppDelegate:
JCreateViewController *create = [[JCreateViewController alloc] init];
[create.navigationBar addLeftButtonWithTitle:#"Back" type:JButtonTypeArrow];
create.navigationBar.title = #"Entry #17";
[self.window addSubview:create.view];
Declaring it in my header file, then using this:
self.create = [[JCreateViewController alloc] init];
[self.create.navigationBar addLeftButtonWithTitle:#"Back" type:JButtonTypeArrow];
self.create.navigationBar.title = #"Entry #17";
[self.window addSubview:self.create.view];
I don't understand why this makes a difference though. I'd love to know, if anybody does know?
Looks like you're using ARC. Whatever this object is, nothing owns it. Nothing has a strong reference to it, so it gets released, and then at some point it gets deallocated.
JCreateViewController *create = [[JCreateViewController alloc] init];
This is a local variable. When the variable goes out of scope at the end of the method, you can't access that object anymore. Under MRR, this would be a leak. Under ARC, the object is going to die, just like it was in an autorelease pool.
self.create = [[JCreateViewController alloc] init];
By creating a property (presumably strong) and putting the controller into that property, you've given whatever self is an owning reference to the controller. It will now live as long as the property isn't reassigned or set to nil.
The timer fixed things because the timer retains its target (which I believe was the controller (your question is rather unclear)), and the timer itself is retained by the run loop. So the run loop keeps the repeating timer alive and the timer kept your controller alive.
In short, make sure something owns this object and it'll stick around.

Is there any case where [self retain] is valid?

Reading source code of my current project, I see:
[self retain]
in one class, in its init method.
I don't understand exactly the reason.
Reading memory management rules from Apple, I don't see anything about this, and I don't see any hypothetical [self release].
The object is asserting ownership of itself when it is initialised. The only reason I can see that this might be useful is if the object needs to guarantee its own existence until some event has happened. For example, it might run a timer and then release itself when the timer expires.
If it's not documented and there is no corresponding release, it's probably a bug.
Best guess is that the person writing the code had a retain error and this was a "quick fix" around the real problem.
This seems to be probably an error, usually it's not up to the object to retain himself.
I see only one special case: delegate and notification, where you have to be much more careful about your life cycle, but even if this case, release/retain should not be done in the object itself.
Note to Erick:
In case of UIAlert, you can release it before it has been destroyed because the view has been but in the view hiercarchy, and then referenced. So the view will be automatically destroyed when it will be removed from the view hierarchy
It's not wrong to retain self. But seeing it in an init method sounds suspicious. I can't think of a good example of where that would be a good thing to do. Also though, with ARC, you can't even do that so you'd have to think of a better way of doing things. In general, if an object is required to be alive then there would be another object that is holding onto it. Self retaining objects are prone to errors where they will never be released.
If I recall correctly some classes use the self-retain to avoid pre-mature releasing. I would say it's not exactly best practice, but if you know the rules of the game (in this case Obj-C) you can break them (sometimes).
if you have some object, it's like it have healts/ lives. when you created it , it have one live. and. function 'retain' increasing his number of lives +1, release function decreasing his number of lives -1, dealloc decreasing too, alloc increasing

Memory leak using (void) alloc

I have seen a similar line of code floating about in Apples code:
(void)[[URLRequest alloc] initializeRequestWithValues:postBody url:verifySession httpHeader:nil delegate:self];
URLRequest is my own custom class. I didn't write this and I think the guy that did just grabbed it from Apple's example. To me this should leak and when I test it I'm pretty sure it leaks 16 bytes. Would it? I know how to fix it if it does but wasn't sure as it was taken from Apple's code.
EDIT: The problem was with the SDK, not the above code. See answer below for further details
Thought I might update this as after further testing and the release of iOS4 it has changed.
The above code doesn't leak and the memory footprint of the App returns to normal even after 200 iterations of the code. The leak did occur in iOS3 but was very small, in iOS4 it has completely disappeared both in simulator and device.
Some might wonder why you would want to implement this code but it works and make sense when dealing with lots of different NSURLConnections throughout your code running simultaneously.
Yes. This is a leak, which can easily be fixed by adding an autorelease:
[[[URLRequest alloc] initializeRequestWithValues:postBody url:verifySession httpHeader:nil delegate:self] autorelease];
Perhaps a better fix would be to create a class function that does this:
#interface URLRequest
{
// ...
}
// ...
+ (void) requestWithValues:/* ... */
// ...
#end
Then you could simply use [URLRequest requestWithValues: /* ... */] without invoking alloc.
Not at all sure what this code is supposed to accomplish. It does appear to break every single convention about initialization methods. What's the point of returning a void pointer from an initialization method? The entire point of an initialization method is to return an object. Where in Apple's code examples did you see this?
Having said that, I don't see why it would leak. Since it doesn't return an object there is nothing to leak external to the method. There might be something internally that leaks.
Edit:
It basically does an NSURLConnection.
Because we are submitting a lot of
forms with a lot of different values
we put it in an external class. All
the delegate methods like
didFailWithError: are in NSURLRequest
and connectionDidFinishLoading just
passes the data to its delegate. So it
doesn't really need to return anything
as it is done through a delegate
method.
Yeah, you need to redesign this. At present, this method is just a disaster waiting to happening. If nothing else, everyone else looking at this code will be utterly confused about what you are doing.
If you have no need to retain the object created, then move its allocation and clean up entirely within a method. Change the method name prefix from "initialize" to something like "setup", "configure", "acquire" etc so the name doesn't imply that it creates and returns and object.
If you need a one shot instance of a particular class, use a class method like Michael Aaron Safyan suggested (again without initialize in the name.) The class method should internally initialize an instance, perform the operations needed, return the data to wherever, then dealloc the instance.
That way, you won't have to worry about leaks and everyone else who may read your code (including yourself months down the road) will immediately understand what the code does.

UISlider setValue "Leaking"

Hey hope someone can help as I am at my wits end with this!?
I have a UISlider. I would like it to move as progress of a task takes place (playing music).
Im setting its value as the continues events happen. (progress through the track)
-(void)updateSlider:(float)value {
NSLog(#" %f ",value);
[timeIndexSlider setValue: value animated:YES];
}
Logs state that the float value is fine..
but its just doesn't move and I get the no autorelease pool - just leaking message, that you would get from a thread without one in the console. There is no thread involved on my part.
Is there a problem updating a UISlider this often?
Is there another way of controlling the sliders movement?
Cheers
I think you're getting updates on another thread and then calling into UIKit on that thread.
Try doing a performSelectorOnMainThread with a new method that does the update (maybe taking an NSNumber object).
Are you retaining a reference to the UISlider? If not, you could be calling -setValue:animated: on a nil reference. Objective-C will allow this, without actually performing the method.
This could potentially explain why you are getting the correct float value passed into the function, but are not getting any updates...
Set a breakpoint as suggested, and make sure that the UISlider reference is not nil.
If not, try posting some code so that we can take a look.
Let us know how it goes,
Tom