Re: [pool release] error
Re: [pool release] error
- Subject: Re: [pool release] error
- From: mmalc Crawford <email@hidden>
- Date: Fri, 26 Dec 2008 09:13:40 -0800
On Dec 26, 2008, at 8:29 AM, Steve Wetzel wrote:
Does anyone know why the follow code produces an error on [pool
release]?. I get the following error :
"*** -[NSDecimalNumber release]: message sent to deallocated
instance 0x10c310". How am I overreleasing anything
There are so many problems here it's difficult to know where to start.
Before asking any memory management question along these lines, you
should first try using the Clang/LLVM static analyzer (<http://clang.llvm.org/StaticAnalysis.html
>) which will reveal several basic errors in your code.
Because of the peculiar structure of your example, though, it doesn't
actually pick up the main problems.
Overreleases here:
[decimalNumber release];
decimalNumber = [tempNum decimalNumberByDividingBy:tempDenom];
and here:
[numerator release];
numerator = [NSNumber numberWithInteger:n];
In both cases you're assigning to your instance variables objects you
don't own.
Review <http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Tasks/MemoryManagementRules.html
>...
You could avoid these problems by following the basic advice in the
Practical Memory Management article in the Memory Management
Programming Guide (<http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html
>):
"Sometimes it might seem tedious or pedantic, but if you use accessor
methods consistently the chances of having problems with memory
management decrease considerably. If you are using retain and release
on a class’s instance variables throughout your code, you are almost
certainly doing the wrong thing."
Memory management aside:
NSDecimalNumber *tempNum = [NSDecimalNumber decimalNumberWithString:
[numerator stringValue]];
NSDecimalNumber *tempDenom = [NSDecimalNumber decimalNumberWithString:
[denominator stringValue]];
tempNum = [NSDecimalNumber decimalNumberWithString:[numerator
stringValue]];
tempDenom = [NSDecimalNumber decimalNumberWithString:[denominator
stringValue]];
Here you're creating two objects only to replace them with equal
objects in the next lines.
Throughout, you're transforming numbers into strings so that you can
create a decimal number. This is horrendously inefficient. At a
guess, you did this is because you looked only at the documentation
for NSDecimalNumber and found decimalNumberWithString: et al. and
didn't look at its superclass -- NSNumber, which means you could use
+numberWithInteger: and -initWithInteger: et al. with NSDecimalNumber
as well. Given what your aims are, it would seem reasonable to use
NSDecimalNumber throughout.
Finally, from the perspective of style:
-(void)setNumerator:(NSInteger)n {
[numerator release];
numerator = [NSNumber numberWithInteger:n];
(and going back in part to the issue of using accessor methods) this
is poor practice. Typically you'd expect a get and set accesor for
numerator which get and set a value of the same type as the
corresponding instance variable. (This is most easily done now using
declared properties -- see <http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Articles/chapter_5_section_1.html
>). If you want to do something else as well, provide a differently-
named method, e.g.
-(void)setNumeratorAsInteger:(NSInteger)n {
NSDecimalNumber *number = [[NSDecimalNumber alloc]
initWithInteger:n];
[self setNumerator:number];
[number release];
}
(assuming you decide to use NSDecimalNumber throughout...).
then:
-(void)setNumerator:(NSDecimalNumber *)newNumerator {
if (numerator != newNumerator) {
[numerator release];
numerator = [newNumerator retain];
if([denominator integerValue] != 0) {
[self updateDecimalNumberWithFraction];
}
}
}
(note use of -integerValue for consistency).
mmalc
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden