EXC_BAD_ACCESS in didAccelerate on phone move - iphone

I'm doing the following:
- (void) accelerometer: (UIAccelerometer *)accelerometer didAccelerate: (UIAcceleration *)acceleration {
if (self.lastAcceleration) {
double i = self.lastAcceleration.x;
It works fine until I actually tilt the phone. Then I get EXC_BAD_ACCESS on the last line. lastAcceleration is a property with a retain. When I look at "x" in the debugger, it has a large negative value. Why would that throw a EXC_BAD_ACCESS exception only on tilt?
-- EDIT (Since this answer applies to responses below) --
I added this and now it works:
- (void)dealloc {
[lastAcceleration release];
Why would that matter? Also, should it be
[self.lastAcceleration release];
I wasn't previously releasing lastAcceleration anywhere. Here is the header declaration:
#interface MyViewController : UIViewController <UIAccelerometerDelegate> {
UIAcceleration *lastAcceleration;
}
#property(nonatomic, retain) UIAcceleration *lastAcceleration;
#end

My hunch is that the accelerometer API has nothing to do with the crash, the code you have shown smells like bad memory management, given that you're mixing ivar and property access I suspect you might be doing the same in other parts you're not showing.
Anyway a couple best practice things:
any object you have a pointer for in your class you should have retained, and conversely when you release it you should also zap the pointer so you don't risk accessing it after it has been deallocated (the exception to this rule are some patterns like the delegate object, where retaining the object would cause a retain cycle, but that's a whole other topic)
ivar setters and getters that are automatically generated via the #synthesized directive will retain and release the object for you for code that simply looks like it's assigning a pointer, so they're pretty handy, but property access (self.something = ...) and ivar access (something = ...) are not equivalent so you have to be careful
One easy way to make sure you don't mix the two up is to do something like this:
#interface MyObject : NSObject
{
SomethingObject *_something;
}
#property (nonatomic, retain) SomethingObject *something;
#end
#implementation MyObject
#synthesize something = _something;
#end
What we're doing here is making the ivar and property names slightly different, so that you are more aware of which one you're using, and the compiler will bark if you use don't use the bare something = ... syntax.
Now the #synthesize'd accessors are something like this:
- (void)setSomething:(SomethingObject *)newSomething
{
[newSomething retain];
[_something release];
_something = newSomething;
}
- (SomethingObject *)something
{
return _something;
}
With all that out of the way, [lastAcceleration release] is a bad thing to do because it isn't also setting the lastAcceleration pointer to nil, you are not guaranteed that it won't be deallocated and if you accidentally use it you are likely to crash.
[self.lastAcceleration release]; is incorrect because accessors take care of all the retain/release stuff for you.
The correct thing to do here is self.lastAcceleration = nil; that, if you look at the accessor code, will release and set the pointer to nil.
What is likely happening is that you are releasing lastAcceleration somewhere without also setting it to nil, and the if (self.lastAcceleration) { check is hitting a released object.

Main reason to have retained properties is to avoid explicit retain/release calls and memory management bugs associated with them. But in dealloc method either way is fine, since object will cease to exist soon.
[self.lastAcceleration release]; - not necessary.
[lastAcceleration release]; self.lastAcceleration = nil;
Both are fine if used in dealloc.
Outside of dealloc use only
self.lastAcceleration = nil;

EXC_BAD_ACCESS is raised when you access released memory. My guess would be that you somewhere released self.lastAcceleration but didn't set it to null.
Are you sure it is related to tilting?

Related

I don't know why I get EXC_BAD_ACCESS ( As Using #property retain )

.h
# interface MyClass : NSObject {
UILabel *mTextLabel;
}
#property (nonatomic, retain) UILabel *mTextLabel;
and Declare #synthesize mTextLabel in the MyClass.m;
and release the object like this.
[self setMTextLabel:nil];
[mTextLabel release];
NSLog (#"%d",[mTextLabel retainCount]);
This result is 0. and I have not found any error or interrupt.
But. When I release mTextLabel like this. I have just got EXC_BAD_ACCESS
[mTextLabel release];
[self setMTextLabel:nil];
I don't understand why it happen. Plz help me.
When you have a synthesized property with the retain attribute, the synthesized setter calls release on the old ivar before it sets the new value.
Here is an expanded view of what is happening in the first example:
[mTextLabel release];
mTextLabel = nil;
[mTextLabel release];
Since calling a method on a nil pointer does nothing, there is no problem.
In the second example, here is what is happening:
[mTextLabel release];
[mTextLabel release];
mTextLabel = nil;
See the problem?
Edit: it is also worth noting that inspecting the retain count of an object is rarely useful, as any number of Cocoa classes may retain it for their own purposes. You just need to be sure that every time you call retain, alloc, copy or new on an object, there is a matching release or autorelease somewhere in your code.
The problem is you are calling release then you are setting the property to nil which also sends a release to mTextLabel before setting it to nil. This is what happens when the property is defined as copy or retain. All you need is the following code.
[mTextLabel release];
mTextLabel = nil;
Edit:
I would like to add that in your code outside of init and dealloc it is completely fine to call self.mTextLabel = nil to properly release if necessary and nil the value of the property. It is however recommended to NOT use the property in the init/dealloc calls. In those cases you will want to create / release the objects directly to avoid the side effects of the accessor.
The value is already released when you do [self setMTextLabel:nil]. You don't need to release the value explicitly (unless you created the value using an init or copy method, in which case you should release it as soon as you've assigned to self.mTextLabel).
Note that retainCount has a return type of NSUInteger, so cannot ever be negative. So checking to make sure the retain count is zero and not -1 doesn't work.

Objective-C method to nullify object

i have some trouble writing a method in Objective-C to make an object nil. Here is some example :
#interface testA : NSObject
{
NSString *a;
}
#property (nonatomic, retain) NSString *a;
+(testA*)initWithA:(NSString *)aString;
-(void)displayA;
-(void)nillify;
#end
#implementation testA
#synthesize a;
+(testA*)initWithA:(NSString *)aString{
testA *tst=[[testA alloc] init];
tst.a=aString;
return [tst autorelease];
}
-(void)displayA{
NSLog(#"%#",self.a);
}
-(void)nillify{
self=nil;
}
- (void)dealloc {
[a release];
[super dealloc];
}
#end
int main(int argc, char **argv){
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
testA *test=[testA initWithA:#"some test"];
[test displayA];
test=nil;
//[test nillify];
NSLog(#"after setting to nil");
[test displayA];
[pool release];
return 0;
}
Apparently , when I set test object to nil and then call some method on it nothing happens , but if i call nillify instead of directly setting it to nil , displayA method works normally like test object is still there. Is there a workaround for nillify method to function properly ?
Your help is much appreciated !
You can't actually do something like this, because setting 'self' to nil only has any effect within the scope of that method (in your case, 'nilify'). You don't have any actual way to effect the values of pointers located on other parts of the stack or in random places in the heap, for example.
Basically any code that holds a reference to some object is responsible for maintaining and clearing those references itself. If you have some use case where random sections of code may need references to "live" objects of some kind, but where you'd want those object references to go away in response to some external event (maybe a user tracking system or something), you could do something with notifications, but the various modules tracking those "live" objects would still be responsible for listening for notifications and cleaning up references when they received them.
The 'nilify' thing, however, can't possibly work.
You cannot do what you're trying to do. self is just a local reference to an object that actually exists elsewhere. Setting it to nil doesn't mean anything. An object doesn't, in general, own itself, and it certainly doesn't control other objects' references to it. It's up to the owning objects to manage its lifetime.
There are a few things wrong with your code.
First, by convention, class names start with an uppercase letter. Please stick to these naming conventions as it will make it harder for other developers to work with your code (and even confuse you).
Next, your initWithName:... According to the naming conventions, a method with init in its name should be an instance method, not a class method. So either name it newWithName: or turn it into an instance method like this:
-(testA*)initWithA:(NSString *)aString{
self = [super init];
if (!self) return nil;
tst.a=aString;
return self;
}
If you keep it as class method (and name it newWithName:) you should not return a autoreleased object since according to the naming conventions method that start with init... or new... return a retained object. If you do not follow these conventions, the static analyzer will give you "false" warnings and it will become useless for you.
Now for the reason your nillify doesn't work: the self is in fact an argument to a method. Under the hood, your nillify method actually has two arguments that you do not see: the self pointer and the selector pointer. This means, self is actually a variable on the stack. And if you overwrite it, you only overwrite that stack variable but that doesn't influence your test variable which is somewhere else.
As an example, consider a method - (void)foo:(NSString *)bar;. The compiler turns it into the equivalent of the C function (void) foo(id self, SEL _cmd, NSString *bar).

#property retain - iPhone

I am newbie to iPhone programming. I have the following doubt which is stopping me to go ahead. Please consider the following code:
---------.h------
#interface myClass: UIViewController
{
UIImage *temp;
}
#property (nonatomic, retain) UIImage *temp;
---------.m------
#interface myClass
#synthesize temp;
-(void) dealloc
{
[temp release];
[super dealloc];
}
The above is the only program code. Thats it ... nothing else. Do I need to declare [temp release] in dealloc method even though I am not using the property accessor method in my program at all. What if I don't declare [temp release] in dealloc. Will that create memory leak as I am releasing something which I haven't retained as I am not calling property accessor method.
Also when i print retain count for temp why does it show 0 even though it is getting retained in #property.
Thanks in advance
If no value has ever been assigned to (an instance of) myClass.temp, then there won't be a leak. But you should release it in your dealloc.
#property is only a declaration that instance of myClass will have this property. You need to assign it a value before that value gets retained.
myClass *instance = [[myClass alloc] init];
// instance will now retain the value passed in
// and is therefore responsible for releasing it
instance.temp = [UIImage imageNamed:#"whatever"];
// if instance is not retained anywhere else,
// its dealloc will be called
[instance release];
On a sidenote, you should give your classes names that start with an uppercase
letter, i.e. MyClass. Not required, but makes things clearer.
You can also use self.temp = nil; in your dealloc You're sorta not supposed but it kinda works better and looks cleaner. It's a bit of an iffy subject...
What you are doing is correct. Scroll to the "dealloc" section of this Apple Doc: Declared Properties
Soon, however, these properties will be cleaned up automatically when you synthesize them (in the next Cocoa update) -- that being said, a convention I have personally began to follow so that my code works in the future is setting self.temp = nil; in dealloc instead of sending a release message (read the apple doc i posted, it explains this). The accessor method created at runtime releases the object first, so for me and quite a few other devs, this is a better/safer way of cleaning up declared properties in our dealloc.
Your code is correct.
The general rule is that, for all variables you declare in #interface, you must clean them up in -dealloc. Some variables will need to be released, others just need to be nil'd out, depending on how you've declared the #property.
In your example above, temp may never have been given a value explicitly by you, but the ObjC runtime will have initialized the value of temp to nil when an instance of your class gets allocated.
Sending a -release to a nil object is generally not a problem, so the [temp release] is fine. It's a no-op. When temp has a non-nil value in -dealloc, the [temp release] gets to do its job of freeing up the memory.
If you need temp to have a non-nil value on creation, you'll need to implement the -init method and make sure it gets some value. While your class is legitimate & functional without an -init method, you really should get in the habit including one in every custom class you design.
You'll need the default initializer at a minimum: -init. You may also want to design a more detailed initializer that could be used to give your temp ivar an a value, like -initWithImage:
Here's what you should also be including in your class:
#implementation MyClass
...
- (id) init {
self = [super init];
if (self != nil) {
// The minimal default initializer.
// temp will already have a value of nil, so you don't need necessarily
// need to do anything more, unless temp needs a real value on initialization.
}
return self;
}
- (void) dealloc {
...
}
#end
To implement a more detailed initializer, which would be known as the designated initializer, you would to something like this:
#implementation MyClass
...
- (id) initWithImage:(UIImage *)newImage {
self = [super init];
if (self != nil) {
temp = [newImage retain];
}
return self;
}
// Implement the default initializer using your more detailed initializer.
- (id) init {
// In this default initializer, every new instance comes with a temp image!
return [self initWithImage:[UIImage imageNamed:#"foobar"]];
}
- (void) dealloc {
...
}
#end
Here, the designated initializer -initWithImage: is the authoritative initializer. All other initializers, including -init, get implemented using -initWithImage:.
You get to exercise a lot of discretion over whether to implement any initializers beyond the minimal default initializer. Maybe -init is good enough for your purposes. That's fine. Sometimes more detailed initializers make using the class more convenient. Experience (and the Force) will be your guide.
Note that I didn't use the generated property accessor in either initializer method. If you aren't required by circumstances, you should generally avoid using property accessors in -init methods and -dealloc, primarily because of potential pain-in-the-ass issues with side effects of automatic key-value coding notifications.
The initializer and dealloc methods play a special role in a class. As the class designer, it is your responsibility to set and clean up instance variables in these methods. A good rule of thumb is to leave the use of synthesized property accessors for the callers of your class, and the implementation of other methods in the class.
When doing initialization of an instance, or deallocation, you can and should touch the ivars directly. They're yours. You declared them, so you can handle them directly. When implementing other methods in your class, you generally should use the property accessors.
JeremyP's link to the Cocoa Conceptual documentation on objects is a good one. You should definitely read the sections on Objects, and periodically re-read it as you gain more experience writing custom classes of your own. Eventually, it will all start making sense.

What's the best way to release objective-c properties?

I'm new to memory-management, and am reading different things about how to best release properties.
If I have:
in .h:
#property(retain) NSString *myStr;
and in .m:
#synthesize myStr = _iVarStr;
Should my dealloc have:
[_iVarStr release];
or
self.myStr = nil;
or something else?
Thanks!
Both self.myStr = nil and [myStr release] ultimately do the same thing.
Calling [myStr release] is obvious and just releases it.
Meanwhile, the setter method for myStr looks roughly like this:
- (void)setMyStr:(NSString *)newMyStr
{
[newMyStr retain];
[myStr release];
myStr = newMyStr;
}
So when we do self.myStr = nil, we're first retaining a nil object, which does nothing. Then we release the old variable, which is what we want. Finally, we set the pointer to nil.
What's the difference? The latter sets the pointer to nil. This is better because if we (accidentally) send a message to the released object, we crash if the pointer isn't nil (EXC_BAD_ACCESS). Now honestly, since you're in -dealloc, the object is being destroyed anyways, so it wouldn't really matter what you use.
When a property is set to retain then
self.ivar = nil;
will properly manage the memory allocation. For other property types check the at the official documentation page. It also has a bunch of sample code so you can understand what happens "under the hood" for all the options.
Your dealloc should be this:
- (void)dealloc {
[_iVarStr release];
[super dealloc];
}
Although setting the property to nil is possible, I worry about unintended side effects or KVO actions triggered by the change that may not realize the object is currently being deallocated.
I recommend you use self.ivar=nil(the code ivar=nil previously I wrote was wrong) way in dealloc method. Because, if the ivar's property change from retain to assign (or from assign to retain), you don't have to change your code.

Are instance variables set to nil by default in Objective-C?

I'm sorting out some memory issues with my iPhone app and I've just been thinking about some basics. If I setup an ivar and never end up using it in the lifespan of my object, when I call dealloc on it, will that cause a problem? E.g.
#interface testClass {
id myobject;
}
#property (nonatomic, retain) id myobject;
#end
#implementation testClass
#synthesize myobject;
- (id)init {
...
// Do I have to set myobject to nil here?
// So if myobject isn't used the dealloc call to nil
// will be okay? Or can you release the variable without
// having set every object to nil that you may may not use
...
}
...
// Somewhere in the code, myobject may be set to
// an instance of an object via self.myobject = [AnObject grabAnObject]
// but the object may be left alone
...
- (void)dealloc {
[myobject release];
[super dealloc];
}
#end
Instance variables are initialized to 0 before your initializer runs..
Yes, ivars are always initialized to 0/nil/NULL/NO/etc.
However, if it helps you understand what's going on, go for it. The performance impact is negligible. You don't need to do it, but it won't cause any problems if you do.
I find that it is good practice to always set those ivars to nil in the init method. That way, you are absolutely sure that your call to release in the destructor can not cause problems.
If it turns out that Objective-C does automatically set them to nil, and for some reason you find yourself with a speed bottleneck that can be improved upon by removing those assignments (highly unlikely), then you can worry about removing them. In the meantime, set them all to nil and sleep easier :)
update: BJ Homer and Chuck have pointed out that the ivars will automatically be set to zero, so now it comes down to a decision on style.