NSValueTransformer for NSPopupButton on CoreData integer attribute - objective-c

I have a CoreData/SQLite app with an NSPopupButton presenting the possible values for some entity attribute (an integer). It automatically shows the attribute value in the database. The user must be able to assign another value so my code generates an array of all possible values on start-up. In my XIB, I have a NSObject for the button and an NSArrayController for the possible values. Bindings are done and everything works fine.
Of course, using only numbers is not clear for the user, so I created a value transformer to replace numbers by words on the popup button: 1=>Red, 2=>Green, 3=>Blue.
The problem is that only the selected Popup item is replaced by a word. And when I choose another value with the Popup button to modify the entity attribute, it doesn't save it. I see it by selecting another object in the TableView then coming back to the modified one and the Popup will indicate NoValue.
I don't understand why. Thank you for your help.
Here is the code of the header file "ColorOption.h":
#import <Foundation/Foundation.h>
#interface ColorOption : NSArrayController {
IBOutlet NSPopUpButton *colorPopup;
NSArray *theNumbers;
}
#property (retain) NSPopUpButton *colorPopup;
#property (readwrite, copy) NSArray *theNumbers;
#end
#interface StatusTransformer : NSValueTransformer {
}
#end
Here is the code of the implementation file "ColorOption.m":
#import "ColorOption.h"
#implementation ColorOption
#synthesize colorPopup;
#synthesize theNumbers;
-(void)awakeFromNib {
[self setTheNumbers:[NSArray arrayWithObjects:[NSNumber numberWithInt:1],[NSNumber numberWithInt:2],[NSNumber numberWithInt:3],nil]];
StatusTransformer *statusTrans = [[[StatusTransformer alloc] init] autorelease];
[NSValueTransformer setValueTransformer:statusTrans forName:#"StatusTransformer"];
}
#end
#implementation StatusTransformer
+ (Class)transformedValueClass { return [NSString class]; }
+ (BOOL)allowsReverseTransformation { return YES; }
- (id)transformedValue:(id)value {
switch ([value intValue]) {
case 1:
return #"Red";
break;
case 2:
return #"Green";
break;
case 3:
return #"Blue";
break;
default:
return #"";
break;
}
}
-(id)reverseTransformedValue:(id)value {
if ([#"Red" isEqualToString:value]) return [NSNumber numberWithInt:1];
if ([#"Green" isEqualToString:value]) return [NSNumber numberWithInt:2];
if ([#"Blue" isEqualToString:value]) return [NSNumber numberWithInt:3];
return nil;
}
#end

I'm reviewing my questions and see that this one has been left unanswered. However in the meantime I had found the answer which I'll post now so it may help others.
The mistake I did was to define the array of integer values while what I should have done is to define the array of words populating the popup button. Here is the full solution:
Header file :
#import <Cocoa/Cocoa.h>
#interface ColorOption : NSArrayController {
IBOutlet NSPopUpButton *colorPopup;
NSArray *theNames;
}
#property (strong) NSPopUpButton *colorPopup;
#property (readwrite, copy) NSArray *theNames;
#end
#interface StatusTransformer : NSValueTransformer {
}
#end
Implementation file
#import "ColorOption.h"
#implementation ColorOption
#synthesize colorPopup = _colorPopup;
#synthesize theNames = _theNames;
-(void)awakeFromNib {
[self setTheNames:[NSArray arrayWithObjects:[NSString stringWithFormat:#"Red"],[NSString stringWithFormat:#"Green"],[NSString stringWithFormat:#"Blue"],nil]];
StatusTransformer *statusTrans = [[[StatusTransformer alloc] init] autorelease];
[NSValueTransformer setValueTransformer:statusTrans forName:#"StatusTransformer"];
}
#end
#implementation StatusTransformer
+ (Class)transformedValueClass {
return [NSString class];
}
+ (BOOL)allowsReverseTransformation {
return YES;
}
- (id)transformedValue:(id)value {
switch ([value intValue]) {
case 1: {
return #"Red";
break;
}
case 2: {
return #"Green";
break;
}
case 3: {
return #"Blue";
break;
}
default: {
return nil;
break;
}
}
}
-(id)reverseTransformedValue:(id)value {
if ([#"Red" isEqualToString:value]) return [NSNumber numberWithInt:1];
if ([#"Green" isEqualToString:value]) return [NSNumber numberWithInt:2];
if ([#"Blue" isEqualToString:value]) return [NSNumber numberWithInt:3];
return nil;
}
#end
Now in the bindings inspector of Xcode, the value transformer must be applied to "Content Values" and "Selected Object" for the popup button.

Related

How to execute a if loop when i press the convert button objective c, xcode

This is my .h file in xcode
//
// PickerViewController.h
// Picker
//
// Created by jitin on 9/14/14.
// Copyright (c) 2014 jitin. All rights reserved.
//
#import <UIKit/UIKit.h>
#interface PickerViewController : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource> {
IBOutlet UIPickerView *picker;
}
#property (nonatomic, retain) UIPickerView *picker;
#property (weak, nonatomic) IBOutlet UITextField *txtbox1;
#property (weak, nonatomic) IBOutlet UITextField *txtbox2;
#property (weak, nonatomic) IBOutlet UITextField *txtbox3;
#property (weak, nonatomic) IBOutlet UITextField *txtbox4;
-(IBAction)convert:(id)sender;
#end
this is my .m file using xcode
//
// PickerViewController.m
// Picker
//
// Created by jitin on 9/14/14.
// Copyright (c) 2014 jitin. All rights reserved.
//
#import "PickerViewController.h"
#interface PickerViewController ()
#end
#implementation PickerViewController
#synthesize picker;
#synthesize txtbox1, txtbox2, txtbox3, txtbox4;
static NSString *pd[3] = {#"Farenheit", #"Feet", #"Grams"};
static NSString *pd2[3] = {#"Celcius", #"Inches", #"Kilograms"};
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark UIPickerViewDelegate & UIPickerViewDataSource methods
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return 3;
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
{
return pd[row];
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
NSLog(#"didSelectRow: %li, inComponent: %li", row, (long)component);
self.txtbox1.text = pd[row];
self.txtbox2.text = pd2[row];
}
#pragma mark Rotation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
NSLog(#"Current Row Select Value %li", [picker selectedRowInComponent:0]);
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
-(BOOL)shouldAutorotate {
NSLog(#"Current Row Select Value %li", [picker selectedRowInComponent:0]);
return YES;
}
-(IBAction)convert:(id)sender
{
float inValue = [[txtbox3 text] floatValue];
float outValue = ((inValue * (9.0f/5.0f)) + 32);
[txtbox4 setText:[NSString stringWithFormat:#"%3.2f", outValue]];
}
#end
my question is about the convert method/function in my .m file.
I want to do a if loop based on what row is selected in the pickerview. for example. if row 0 is selected, the conversion would be Fahrenheit to Celsius.
if row 1 is selected the conversion would be feet to inches when i hit the convert button. I know I have to use a if loop. But i'm having trouble on what to call in that if loop in order for my statements to execute correctly. Another note. I have not implemented my feets to inches and the grams to kilograms conversion yet. I just wanna get my if loop working first.
Hi #user7897479 and welcome.
My recommendation would be to use a "UnitConversion" class to hold all the relevant information about the units and perform the conversions for you. This separates the responsibilities so that your ViewController only really has the responsibility of passing data between the UI Elements <-> conversion class.
One other thing that i'd like to mention before I get into my full answer:
Naming is very important! Please give meaningful names to your properties/methods/objects/classes -- This will help not only others looking at your code, but yourself going forward maintaining it
Looking at this without much idea about your interface, I have no clue what txtbox1,2,3,4 are for, or for that matter what type of strings pd, pd2 (if I was just looking at them without the literals defined).
Ok, onto some code:
UnitConversion.h:
#import <Foundation/Foundation.h>
typedef enum : NSUInteger {
UnitConversionTypeFarenheightToCelsius,
UnitConversionTypeFeetToInches,
UnitConversionTypeGramsToKilograms,
} UnitConversionType;
NS_ASSUME_NONNULL_BEGIN
#interface UnitConversion : NSObject
- (instancetype _Nullable)initWithUnitConversionType:(UnitConversionType)type;
- (NSString *)nameForConvertFromUnit;
- (NSString *)nameForConvertToUnit;
- (NSString *)runConversionOnValue:(float)value;
#end
NS_ASSUME_NONNULL_END
UnitConversion.m:
#import "UnitConversion.h"
typedef enum : NSUInteger {
ConversionUnitFarenheit,
ConversionUnitFeet,
ConversionUnitGrams,
ConversionUnitCelsius,
ConversionUnitInches,
ConversionUnitKilograms,
} ConversionUnit;
#interface UnitConversion()
#property ConversionUnit convertFromUnit;
#property ConversionUnit convertToUnit;
#property UnitConversionType conversionType;
#property float valueToConvert;
#end
#implementation UnitConversion
- (instancetype _Nullable)initWithUnitConversionType:(UnitConversionType)type {
self = [super init];
if (self) {
_conversionType = type;
switch (type) {
case UnitConversionTypeFarenheightToCelsius: {
_convertFromUnit = ConversionUnitFarenheit;
_convertToUnit = ConversionUnitCelsius;
break;
}
case UnitConversionTypeFeetToInches: {
_convertFromUnit = ConversionUnitFeet;
_convertToUnit = ConversionUnitInches;
break;
}
case UnitConversionTypeGramsToKilograms: {
_convertFromUnit = ConversionUnitGrams;
_convertToUnit = ConversionUnitKilograms;
break;
}
default:
break;
}
}
return self;
}
- (NSString *)runConversionOnValue:(float)value {
self.valueToConvert = value;
NSString *convertedValue = #"Undefined";
switch (self.conversionType) {
case UnitConversionTypeFarenheightToCelsius:
convertedValue = [self _convertFarenheightToCelsius];
break;
case UnitConversionTypeFeetToInches:
convertedValue = [self _convertFeetToInches];
break;
case UnitConversionTypeGramsToKilograms:
convertedValue = [self _convertGramsToKilograms];
break;
default:
break;
}
return convertedValue;
}
- (NSString *)_convertFarenheightToCelsius {
return [NSString stringWithFormat:#"%.2f", (self.valueToConvert - 32.0f) * (5.0f/9.0f)];
}
- (NSString *)_convertFeetToInches {
return [NSString stringWithFormat:#"%.2f", self.valueToConvert / 12.0f];
}
- (NSString *)_convertGramsToKilograms {
return [NSString stringWithFormat:#"%.2f", self.valueToConvert / 1000.0f];
}
- (NSString *)nameForConvertFromUnit {
return [self _nameForConversionUnit:self.convertFromUnit];
}
- (NSString *)nameForConvertToUnit {
return [self _nameForConversionUnit:self.convertToUnit];
}
- (NSString *)_nameForConversionUnit:(ConversionUnit)unit {
NSString *unitName = #"Default Unit";
switch (unit) {
case ConversionUnitFarenheit: {
unitName = #"Farenheit";
break;
}
case ConversionUnitFeet: {
unitName = #"Feet";
break;
}
case ConversionUnitGrams: {
unitName = #"Grams";
break;
}
case ConversionUnitCelsius: {
unitName = #"Celsius";
break;
}
case ConversionUnitInches: {
unitName = #"Inches";
break;
}
case ConversionUnitKilograms: {
unitName = #"Kilograms";
break;
}
default:
break;
}
return unitName;
}
#end
ConversionViewController.m:
#import "ConversionViewController.h"
#import "UnitConversion.h"
#interface ConversionViewController () <UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate>
#property (strong, nullable) IBOutlet UIPickerView *conversionPicker;
#property (strong, nullable) NSArray <UnitConversion *> *unitConversionArray;
#property (strong, nullable) IBOutlet UILabel *convertFromLabel;
#property (strong, nullable) IBOutlet UILabel *convertToLabel;
#property (strong, nullable) IBOutlet UITextField *convertFromValue;
#property (strong, nullable) IBOutlet UITextField *convertToValue;
#end
#implementation ConversionViewController
- (void)viewDidLoad {
[super viewDidLoad];
// setup the conversion we want to do and put them into our data structure
UnitConversion *degreesConversion = [[UnitConversion alloc] initWithUnitConversionType:UnitConversionTypeFarenheightToCelsius];
UnitConversion *inchesToFeet = [[UnitConversion alloc] initWithUnitConversionType:UnitConversionTypeFeetToInches];
UnitConversion *gramsToKilo = [[UnitConversion alloc] initWithUnitConversionType:UnitConversionTypeGramsToKilograms];
self.unitConversionArray = #[degreesConversion, inchesToFeet, gramsToKilo];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// by default select the first row
[self.conversionPicker selectRow:0 inComponent:0 animated:NO];
}
- (IBAction)convert:(id)sender {
NSInteger pickerRow = [self.conversionPicker selectedRowInComponent:0];
if (pickerRow >= 0) {
// grab our associated UnitConversion based on our backing unit conversion array
// the index matches up with the index selected for the picker row
UnitConversion *conversion = [self.unitConversionArray objectAtIndex:pickerRow];
// run the conversion
NSString *convertedValue = [conversion runConversionOnValue:[self.convertFromValue.text floatValue]];
// set the converted value to our result field
self.convertToValue.text = convertedValue;
}
}
- (NSInteger)numberOfComponentsInPickerView:(nonnull UIPickerView *)pickerView {
return 1;
}
- (NSInteger)pickerView:(nonnull UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return 3;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
// clear out our input and output fields
self.convertFromValue.text = #"";
self.convertToValue.text = #"";
// set the labels to alpha 0 because we going to fade in the change
self.convertFromLabel.alpha = 0.0f;
self.convertToLabel.alpha = 0.0f;
// determine which conversion is selected from the picker view
UnitConversion *conversion = [self.unitConversionArray objectAtIndex:row];
// set our labels to reflect that
self.convertFromLabel.text = [conversion nameForConvertFromUnit];
self.convertToLabel.text = [conversion nameForConvertToUnit];
// now animate the fade in of our label names
[UIView animateWithDuration:0.2 animations:^{
self.convertFromLabel.alpha = 1.0f;
self.convertToLabel.alpha = 1.0f;
}];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
// our titles should be in the form of "Feet to Inches"
UnitConversion *conversion = [self.unitConversionArray objectAtIndex:row];
return [NSString stringWithFormat:#"%# to %#", [conversion nameForConvertFromUnit], [conversion nameForConvertToUnit]];
}
#pragma mark - UITextFieldDelegate
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
// only allow numbers decimal and negative
NSCharacterSet *numbersOnly = [NSCharacterSet characterSetWithCharactersInString:#"0123456789.-"];
NSCharacterSet *characterSetFromTextField = [NSCharacterSet characterSetWithCharactersInString:textField.text];
// don't allow the text field to change if the user attempts to input something else
BOOL stringIsValid = [numbersOnly isSupersetOfSet:characterSetFromTextField];
return stringIsValid;
}
#end
Here's an example of what that Code produces after generating a simple interface:
While this does seem like overkill for the example, it makes it a lot easier to expand upon it (for example if you wanted to add additional conversion types, or re-use the conversion class somewhere else).

Information in text fields do not get retained objective c

This is a simple program that takes two numbers inputed by the user in two separate text fields and adds them together when the 'Add' button is clicked. The way I have done this is by subclassing NSTextField into a class called MyTextField. I believe my error has something to do with memory leaks, but being an inexperienced programmer, I'm not quite sure how to deal with allocating and deallocating memory.
The problem is: When I click the Add button, it works perfectly. However, when I click it again, it does not show the correct amount. It keeps taking my inputs as nil and outputting 0. I have attached my code.
Note: I know that this is much more complicate than it needs to be! I am simply showing a simpler version of a much more complicated program that displays the exact same error.
MyTextField.h
#import <Cocoa/Cocoa.h>
#interface MyTextField : NSTextField
#property (strong) NSString* number;
#property double dblNum;
-(id)initWithNumber:(NSString *)number;
-(NSString *)getNumber;
-(void)setNumber;
-(double)getDblNum;
-(void)setDblNum;
-(double)calcSum:(MyTextField *)other;
-(NSString *)description;
#end
MyTextField.m
#import "MyTextField.h"
#implementation MyTextField
-(id)initWithNumber:(NSString *)number{
self = [super init];
if (self) {
if ([number length] > 0){
_number = number;
}else{
_number = #"0";
}
[self setDblNum];
}
return self;
}
- (id)init {
return [self initWithNumber:[self getNumber]];
}
-(NSString *)getNumber{
return _number;
}
-(void)setNumber{
_number = [self stringValue];
}
-(double)getDblNum{
return _dblNum;
}
-(void)setDblNum{
_dblNum = [_number doubleValue];
}
-(double)calcSum:(MyTextField *)other{
return [self getDblNum] + [other getDblNum];
}
- (NSString *)description{
return [NSString stringWithFormat: #"Number: %f", _dblNum];
}
#end
ViewController.h
#import <Cocoa/Cocoa.h>
#import "MyTextField.h"
#interface ViewController : NSViewController
#property (strong) IBOutlet MyTextField *valueOne;
#property (strong) IBOutlet MyTextField *valueTwo;
#property (strong) IBOutlet NSTextField *answer;
- (IBAction)btnAdd:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#import "MyTextField.h"
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)setRepresentedObject:(id)representedObject {
[super setRepresentedObject:representedObject];
}
- (IBAction)btnAdd:(id)sender {
_valueOne = [[MyTextField alloc] initWithNumber:[_valueOne stringValue]];
_valueTwo = [[MyTextField alloc] initWithNumber:[_valueTwo stringValue]];
double ans = [_valueOne calcSum:_valueTwo];
_answer.stringValue = [NSString stringWithFormat:#"%.2f", ans];
}
#end
P.S. Sorry for the annoying amount of code. Thanks!
Your btnAdd: is where the problem is.
- (IBAction)btnAdd:(id)sender {
_valueOne = [[MyTextField alloc] initWithNumber:[_valueOne stringValue]];
_valueTwo = [[MyTextField alloc] initWithNumber:[_valueTwo stringValue]];
double ans = [_valueOne calcSum:_valueTwo];
_answer.stringValue = [NSString stringWithFormat:#"%.2f", ans];
}
Each time the button is tapped, you're recreating both MyTextField instances. Instead, you simply need to get & set the values from your existing valueOne and valueTwo outlets, like:
- (IBAction)btnAdd:(id)sender {
double value1 = [_valueOne.text doubleValue];
double value2 = [_valueTwo.text doubleValue];
double ans = value1 + value2;
_answer.stringValue = [NSString stringWithFormat:#"%.2f", ans];
}
Obviously, you need to check the validity of the valueOne and valueTwo text strings.
You really don't need a MyTextField subclass, because it's not doing anything except converting strings to doubles (and vice versa).

Objective C newbie, one method can change UI elements, others can not

thanks in advance for any input. I have been trying to write a program that interprets a serial command into text change in a label. I can change the label text easily with an Action attached to a button, but for some reason all my attempts at changing the label text outside that button action result in nothing being changed.
// MasterViewController.m
//
// Created by Daniel Payne on 2/28/15.
// Copyright (c) 2015 Daniel Payne. All rights reserved.
//
#import "MasterViewController.h"
#interface MasterViewController ()
#property (strong) IBOutlet NSTextField *score;
#property (nonatomic, strong) ORSSerialPort *serialPort;
#property (nonatomic, strong) MasterViewController *masterView;
#end
static MasterViewController *serialPortHelper = nil;
void connectPort(void) {
ORSSerialPort *serialPort = [ORSSerialPort serialPortWithPath:#"/dev/tty.usbmodem1411"];
serialPortHelper = [[MasterViewController alloc] init];
serialPortHelper.serialPort = serialPort;
serialPort.delegate = serialPortHelper;
serialPort.baudRate = #9600;
NSLog(#"port open");
[serialPort open];
}
int main(int argc, const char * argv[]) {
connectPort();
return NSApplicationMain(argc, argv);
}
#implementation MasterViewController
- (IBAction)pushButton:(id)sender {
[self.score setStringValue:#"1"]; //works
}
- (void)viewDidLoad {
[super viewDidLoad];
}
-(void)awakeFromNib
{
NSLog(#"View controller instance with view: %#", self.view);
}
- (void)serialPort:(ORSSerialPort *)serialPort didReceiveData:(NSData *)data
{
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if ([string rangeOfString:#"g"].location == NSNotFound) {
NSLog(#"no goal");
} else {
[self.score setStringValue:#"1"]; //does not work
NSLog(#"GOOOOAL");
}
}
- (void)serialPortWasRemovedFromSystem:(ORSSerialPort *)serialPort
{
self.serialPort = nil;
}
- (void)serialPort:(ORSSerialPort *)serialPort didEncounterError:(NSError *)error
{
NSLog(#"%s %# %#", __PRETTY_FUNCTION__, serialPort, error);
}
- (void)serialPortWasOpened:(ORSSerialPort *)serialPort
{
NSLog(#"Serial port %s was opened", [serialPort.name UTF8String]);
}
#end
The instance of MasterViewController that is listening to your serial port is not the same one that you are seeing on screen.
You create a new one and assign it to a static variable - this is not the same one you have loaded from a nib with all its outlets connected.
Log self in both methods to confirm.

Objective-C NSMutableArray not saving objects

I'm learning Objective-C (having come from Java) and I'm am attempting to program a small Cocoa app on OSX. I am thinking with my Java hat on and that's probably why this isn't working. Basically I am trying to get an object of type Car added to an NSMutableArray on a button click but although the rest of the code seems to work, nothing is being saved to the array. I can't figure out why - help is appreciated. Here's the code:
#import "AppDelegate.h"
#import "Car.h"
#import "PileInterface.h"
#interface AppDelegate ()
#property (weak) IBOutlet NSWindow *window;
#end
#implementation AppDelegate
PileInterface *myStack;
Car *car;
//initialise Stack
-(void)stack{
myStack = [[PileInterface alloc]init];
//initialise myStack in Pileinterface
[myStack initialise];
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
//corrected code here to call the stack method above
//initialise myStack by calling stack method
[self stack];
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}
- (IBAction)addBtn:(NSButton *)sender {
car = [[Car alloc]init];
NSString *licence = [_txtField1 stringValue];
NSString *model = [_txtField2 stringValue];
NSString *colour = [_txtField3 stringValue];
if ([myStack isFull] == false) {
// add Car objects to car
//set licence
[car setLicence:licence];
// set model
[car setModel:model];
//set colour
[car setColour:colour];
//add to stack
[myStack push:car];
//append to textarea
NSString *message = licence;
[_txtArea setStringValue:message];
[_txtField2 setIntegerValue:[myStack size]];
} else {
NSString *message2 = #"Rejected. There are more than 4 cars currently for recycling!";
[_txtArea insertText:message2];
}
}
#end
Effectively Car is the object I want to get into myStack (which is a stack inside PileInterface, which also contains the NSMutableArray)
PileInterface implementation code here:
#import "PileInterface.h"
#implementation PileInterface
//arraylist of objects
NSMutableArray *list;
//initialise array
-(void)initialise{
list = [[NSMutableArray alloc]init];
}
-(void) push:(id) o{
[list insertObject:o atIndex:0];
}
-(id) pop{
if ([list count] > 0) {
NSObject *temp =[list objectAtIndex:0];
[list removeObjectAtIndex:0];
return temp;
} else {
return nil;
}
}
-(BOOL) isEmpty{
if ([list count] == 0) {
return true;
} else {
return false;
}
}
-(int) size{
return (int)[list count];
}
-(BOOL) isFull{
if ([list count] > 4) {
return true;
} else {
return false;
}
}
#end
Help Appreciated!

I can not figure out how to resolve SIGABRT error in Xcode

I am working on a basic calculator app, following a tutorial for an iTunes U class. I thought I had worked it out perfectly but when I go to run the application in the simulator, I get an unexpected error. The calculator works by entering the number, pressing the enter button, entering the second number, then the enter button and then the operation. It allows me to append digits to form a multi-digit number, but as soon as I press "enter" it quits out and says "Thread 1: Program received signal: "SIGABRT."" I have double and triple checked my code and cannot seem to find anything wrong, so i thought i would post it all on here and see if you guys can figure it out. Thanks in advance!
CalculatorBrain.h
#import <Foundation/Foundation.h>
#interface CalculatorBrain : NSObject
- (void)pushOperand:(double)operand;
- (double)performOperation:(NSString *)operation;
#end
CalculatorBrain.m
#import "CalculatorBrain.h"
#interface CalculatorBrain()
#property (nonatomic, strong) NSMutableArray *operandStack;
#end
#implementation CalculatorBrain
#synthesize operandStack = _operandStack;
- (NSMutableArray *)operandStack
{
if (!_operandStack) {
_operandStack = [[NSMutableArray alloc] init];
}
return _operandStack;
}
- (void)pushOperand:(double)operand
{
NSNumber *operandObject = [NSNumber numberWithDouble:operand];
[self.operandStack addObject:operandObject];
}
- (double)popOperand
{
NSNumber *operandObject = [self.operandStack lastObject];
if (operandObject) [self.operandStack removeLastObject];
return [operandObject doubleValue];
}
- (double)performOperation:(NSString *)operation
{
double result = 0;
if ([operation isEqualToString:#"+"]){
result = [self popOperand] + [self popOperand];
} else if ([#"*" isEqualToString:operation]) {
result = [self popOperand] * [self popOperand];
} else if ([operation isEqualToString:#"-"]) {
double subtrahend = [self popOperand];
result = [self popOperand] - subtrahend;
} else if ([operation isEqualToString:#"/"]) {
double divisor = [self popOperand];
if (divisor) result = [self popOperand] / divisor;
}
[self pushOperand:result];
return result;
}
#end
CalculatorViewController.h
#import <UIKit/UIKit.h>
#interface CalculatorViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *display;
#end
CalculatorViewController.m
#import "CalculatorViewController.h"
#import "CalculatorBrain.h"
#interface CalculatorViewController()
#property (nonatomic) BOOL userIsInTheMiddleOfEnteringANumber;
#property (nonatomic, strong) CalculatorBrain *brain;
#end
#implementation CalculatorViewController
#synthesize display;
#synthesize userIsInTheMiddleOfEnteringANumber;
#synthesize brain = _brain;
- (CalculatorBrain *)brain
{
if(!_brain) _brain = [[CalculatorBrain alloc] init];
return _brain;
}
- (IBAction)digitPressed:(UIButton *)sender {
NSString *digit = [sender currentTitle];
if (self.userIsInTheMiddleOfEnteringANumber) {
self.display.text = [self.display.text stringByAppendingString:digit];
} else {
self.display.text = digit;
self.userIsInTheMiddleOfEnteringANumber = YES;
}
}
- (IBAction)enterPressed
{
[self.brain pushOperand:[self.display.text doubleValue]];
self.userIsInTheMiddleOfEnteringANumber = NO;
}
- (IBAction)operationPressed:(UIButton *)sender
{
if (self.userIsInTheMiddleOfEnteringANumber) {
[self enterPressed];
}
NSString *operation = [sender currentTitle];
double result = [self.brain performOperation:operation];
self.display.text = [NSString stringWithFormat:#"%g", result];
}
#end
Open CalculatorViewController.xib file in Xcode and right-click the "File's Owner".
Check the appearing pop-up if you have any linked properties listed that are not implemented in the CalculatorViewController.h file (according to the above posted code, the only properties linked from .xib to .h should be a UILabel called "display". Delete all invalid linked properties, if any is available (invalid linked properties would be marked with a yellow warning sign).
Expand your project Executable and right click on it. and click on GetInfo->Argument tag aat end of the window you see plus and minus sign button click on + sighn button and write
Name Value
NSZombieEnabled YES
then after execute your project and whenever crash your application click on run munu-> console you see there why your application crash. please try this may be this will help you.