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
Related
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.
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
I have a view controller that is created by the app delegate - it's the first one shown in the app.
In its interface I declare
float lengthOfTime;
I also set it as a property:
#property (nonatomic) float lengthOfTime;
And in it's implemetation:
#synthesize lengthOfTime;
In the class viewDidLoad method, I set the value:
self.lengthOfTime = 3.0f;
However, after this, the value is always zero.
No errors, no compile warnings, nothing. Just zero.
The class is instantiated, it is showing in the view, so I'm pretty sure it's not a nil reference.
I've searched all over Google and can't figure it out.
What's going on?!?
:(
The property should be atomic I think. Just declare it as:
#property float lengthOfTime;
Updating primitives is an atomic operation.
I'm not sure if that will solve your problem or not.
The "non-atomic" keyword is for protection from multi-threading issues where one thread gets interrupted in the middle of changing it. You can only interrupt an operation if it takes more than one instruction to perform. Updating a single floating-point value is a one-instruction operation, and therefore cannot be interrupted.
It is possible that your view is reading the value before -viewDidLoad is called. I would try setting the variable in a method that is called before the view is initialized such as -awakeFromNib.
I fixed it and don't know how I did it. That's the worst. Now I don't know how to solve it if it happens again.
I thought it wasn't being initialized, but I removed the line and it still works.
I think I'm even more frustrated than before.
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.
EDIT: I stuck in a single call to manually retain the array right after initializing it, and that fixed it. Dur. Thanks.
I keep an NSMutableArray in a UIScrollView subclass, and I add to it instances of a UIImageView subclass as each is added as a subview. It needs to be a mutable array, as I plan to rearrange their order in the array eventually; this bug is occurring before I even try to do so. I've used NSLogs to show that the array has count 10 up until and including applicationDidBecomeActive: is called in my AppDelegate, and added a timer to fire every 0.001s in the run loop. The first time it fires, it can't find the array anymore! I'm very confused and have been trying to track this down for hours.
The timer's working properly (i.e. when printCount: doesn't access the array, it's fine), it's only when I try to access the array there that it breaks. The regular call to printCount: below works, but the first time the timer fires I What could possibly be happening between these two calls to printCount:?
- (void)applicationDidBecomeActive:(UIApplication *)application {
NSTimer *timer = [[NSTimer scheduledTimerWithTimeInterval:0.001f
target:[viewController view]
selector:#selector(printCount)
userInfo:nil
repeats:YES]
retain];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
[[viewController view] printCount];
}
I've been endlessly stepping through the program with the debugger. The array is correct right up through this point, and its memory address is the same even after its contents are changed. However, there is only object in it afterwards -- its 10 elements get replaced by a single UITouchData instance. No idea where it comes from. None of my event-handling methods attempt to reassign the array or change it. Any ideas what could be going wrong? I'm completely mystified.
Did you -retain the array?
Perhaps your object was released? What happens if you retain it. Does that work or you just get a memory leak?
its 10 elements get replaced by a
single UITouchData instance. No idea
where it comes from.
Is it always a UITouchData instance? Always? -- Cause that would seem like a dead give-away (if its not the SAME every-time) of a memory problem.
I stuck in a call to retain to array right after initializing it, and that fixed it. Dur.
Thank you for the suggestions. As usually happens with problems like these, it was very simple and finally giving in and asking for help triggers a solution and makes me feel stupid. :D
Does the view initialize and release the array?
Are you sure that the NSView isn't released in between?
You could check if the memory address of [viewController view] (== self within printCount) is the same every time your timer calls printCount.