0

I'm trying to figure out why my NSTextFields are only retained in the first method sendVarsToButton but not in the updateTotal method. I need to access the values from the TextField set in the first method but I can't because it seems like my IBOutlets deallocate themselves after the sendVarsToButton method. Can you help me please!?

Here's my .h

#import <Cocoa/Cocoa.h>
#import "TransactionViewController.h"
@class TransactionButtonModel;

@interface TransactionButtonController : TransactionViewController

{
NSMutableArray *buttonsArrays;
TransactionViewController *transactionViewController;
TransactionButtonModel *transactionButtonModel;
}
@property(nonatomic,retain) IBOutlet NSTextField *nom;
@property(nonatomic,retain) IBOutlet NSTextField *descriptionText;
@property(nonatomic,retain) IBOutlet NSTextField *prix;
@property(nonatomic,retain) IBOutlet NSTextField *CPUField;
@property(nonatomic,retain) IBOutlet NSTextField *quantite;
@property(nonatomic,retain) IBOutlet NSTextField *total;

-(void)sendVarsToButton:(NSString *)name:(NSString *)description:(double)price:(double)CPU:(long)tag;
-(void)updateTotal:(int)newQuantity;
-(void)addQuantiteToExistingProduct:(long)tag;
-(IBAction)removeProductFromView:(id)sender;

Here's my .m

#import "TransactionButtonController.h"
#import "TransactionViewController.h"
#import "TransactionButtonModel.h"

@implementation TransactionButtonController
@synthesize prix;
@synthesize nom;
@synthesize descriptionText;
@synthesize CPUField;
@synthesize total;
@synthesize quantite;

//In this method, everything works fine

-(void)sendVarsToButton:(NSString *)name :(NSString *)description :(double)price :(double)CPU:(long)tag
{
[nom setTag:tag];
[descriptionText setTag:tag];
[prix setTag:tag];
[CPUField setTag:tag];
[quantite setTag:tag];
[total setTag:tag];

nom.stringValue = name;
descriptionText.stringValue = description;
[prix setDoubleValue : price];
CPUField.doubleValue = CPU;

total.doubleValue = [TransactionButtonModel calculateButtonTotal:quantite.intValue :prix.doubleValue];

NSLog(@"retain! :%lu",[[prix viewWithTag:tag] retainCount]); // returns 2

[transactionButtonModel release];

}
-(void)updateTotal:(int)newQuantity
{
NSLog(@"retain! :%lu",[[prix viewWithTag:2] retainCount]); //returns 0
[total setDoubleValue:[TransactionButtonModel calculateButtonTotal:newQuantity :prix.doubleValue]]; // value of prix = 0 and prix = null
NSLog(@"Updated! :%i",newQuantity);
}

-(void)dealloc
{
[nom release];
[quantite release];
[prix release];
[total release];
[descriptionText release];
}

Thanks in advance.

  • `retainCount` doesn't do what you'd expect. –  Jun 15 '12 at 17:35
  • What do you mean? When I do `[prix description]` it returns `null`. So my textfield isn't allocated. – Philippe Champigny Jun 15 '12 at 17:37
  • Yes, you're right: it's not allocated. It's not *deallocated* though. If it was a deallocated object that already have died, it would be an invalid non-NULL pointer (to crap). Your object hasn't yet born. –  Jun 15 '12 at 17:41
  • Note; `sendVarsToButton::::::::::::` is an awful method name. Also note that `retainCount` can never return 0. – bbum Jun 16 '12 at 20:34

1 Answers1

1

It sounds like you have a few problems here. In no particular order:

  1. You're releasing transactionButtonModel in sendVarsToButton::::: even though you didn't create it there and there's no particularly obvious reason you'd want to. This seems like probably a memory management error, but it's hard to say without context.

  2. You're looking to the reference counting mechanisms to see why a variable is null. Overreleasing an object does not set variables referencing that object to null — it would just be a junk pointer and probably crash your program. The most likely reasons for a variable to be unexpectedly null are a) methods running in a different order than you expect, or b) having two different instances of your class that you're treating as though they're the same one. My money would be on B in this case. You're probably creating two instances of this class, one of which is actually showing the view and the other being essentially "blank." Try logging self in the two methods and see if it's the same object.

  3. In one method you're logging viewWithTag:tag and in the other you're logging viewWithTag:2 — it's not necessarily a safe assumption that tag is 2.

  4. prix is an NSTextField — why are you asking it for subviews? NSTextField isn't generally expected to have any useful subviews. There seems to be something odd in this design.

  5. Your method names are nuts with all those bare colons. It's hard to read and often leads to mistakes down the line (due to the likelihood of misreading the code when you're not "in the moment" and the fact that it violates the language's idioms).

  6. You're depending on retainCount to track memory management. The value returned by retainCount is questionable at best and often downright deceptive because things get retained and autoreleased all the time, and retainCount won't give you enough information to account for that. If you have a memory management problem (which doesn't appear to be this case with your variable becoming nil), a good approach would be to use Instruments and the debugger to track it down, not random retainCount logging.

Chuck
  • 234,037
  • 30
  • 302
  • 389
  • +1! Thanks! Indeed, I called alloc on this class each time I clicked on the button. So the object was recreated. Now I need to figure out a way to create many subviews from 1 separated nib file with initWithNibNamed from NSViewController without calling alloc and initWithNibNamed more than once! – Philippe Champigny Jun 18 '12 at 11:24