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

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.

Related

Unable to open Plaid Link UI, Spinning indefinetely

The error is as below.
The Handler is being deinitialized before Link has completed or been exited. Did you forget to strongly reference the Handler object returned by Plaid.create?
The functionality is working in the native app using the LinkKit framework. In order to use all the functions in objective C we have included a wrapper on top of it which is as below and when building a native app using the wrapper I am facing the above issue.
Wrapper Code.
// LinkKitSwiftwrapper.h
#import <Foundation/Foundation.h>
#import <LinkKit/LinkKit-Swift.h>
#import <UIKit/UIActivity.h>
NS_ASSUME_NONNULL_BEGIN
#interface LinkKitSwiftWrapper : NSObject
- (void)presentPlaidLinkUsingLinkToken: (NSString *)linkToken completionHandler:(void (^)(NSArray *array))callbackServer;
#property (strong, retain, nonatomic, readwrite) id<PLKHandler> linkHandler;
#end
NS_ASSUME_NONNULL_END
//LinkKitswiftWrapper.m
#import "LinkKitSwiftWrapper.h"
#import <LinkKit/LinkKit-Swift.h>
#import <UIKit/UIKit.h>
#import <LinkKit/LinkKit.h>
#implementation LinkKitSwiftWrapper
static void (^callBackObjectServer)(NSArray *);
- (void) presentPlaidLinkUsingLinkToken: (NSString *)linkToken completionHandler:(void (^)(NSArray *array))callbackServer
{
callBackObjectServer = callbackServer;
PLKLinkTokenConfiguration* linkConfiguration = [PLKLinkTokenConfiguration createWithToken:linkToken
onSuccess:^(PLKLinkSuccess *success) {
dispatch_async(dispatch_get_main_queue(), ^{
NSArray *result = #[#"SUCCESS", success.publicToken];
callBackObjectServer(result);
});
}];
linkConfiguration.onExit = ^(PLKLinkExit * exit) {
if (exit.error) {
NSLog(#"exit with %#\n%#", exit.error, exit.metadata);
} else {
NSLog(#"exit with %#", exit.metadata);
}
};
NSError *createError = nil;
id<PLKHandler> handler = [PLKPlaid createWithLinkTokenConfiguration:linkConfiguration
error:&createError];
self.linkHandler = nil;
if (handler) {
[handler retain]
self.linkHandler = handler;
UIViewController *vc = [LinkKitSwiftWrapper topViewController] ;
[self.linkHandler openWithContextViewController:vc];
} else if (createError) {
NSLog(#"Unable to create PLKHandler due to: %#", createError);
dispatch_async(dispatch_get_main_queue(), ^{
NSArray *result = #[#"ERROR", createError.description];
callBackObjectServer(result);
});
}else{
NSString *errorMessage = #"Unknown error occured while trying to create a Plaid link.";
NSLog(#"%#", errorMessage);
dispatch_async(dispatch_get_main_queue(), ^{
NSArray *result = #[#"ERROR", errorMessage];
callBackObjectServer(result);
});
}
}
+ (UIViewController *)topViewController{
return [self topViewController:[[LinkKitSwiftWrapper keyWindow] rootViewController ]];
}
+ (UIViewController *)topViewController:(UIViewController *)rootViewController
{
if (rootViewController.presentedViewController == nil) {
return rootViewController ;
}
if ([rootViewController.presentedViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *navigationController = (UINavigationController *)rootViewController.presentedViewController;
UIViewController *lastViewController = [[navigationController viewControllers] lastObject];
return [self topViewController:lastViewController];
}
UIViewController *presentedViewController = (UIViewController *)rootViewController.presentedViewController ;
return [self topViewController:presentedViewController];
}
+(UIWindow*)keyWindow
{
UIWindow *foundWindow = nil;
NSArray *windows = [[UIApplication sharedApplication]windows];
for (UIWindow *window in windows) {
if (window.isKeyWindow) {
foundWindow = window;
break;
}
}
return foundWindow;
}
#end
//Native App code
#import "ViewController.h"
#import "PlaidWrapper/LinkKitSwiftWrapper.h"
#interface ViewController ()
#end
static void (^callBackObjectServer)(NSArray *);
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (IBAction)ButtonTouchUpInside:(id)sender {
[ [LinkKitSwiftWrapper new] presentPlaidLinkUsingLinkToken:#"link-sandbox-0f671f81-c144-4160-8a64-0ce51e63dbcd" completionHandler:(void (^)(NSArray* array))callBackObjectServer];
}
#end
Please help.

slider in tableview full demo

for CustomeTableViewCell.h
//
// CustomeTableViewCell.h
// Slider Program
//
// Created by Naeem Shaikh on 21/08/14.
// Copyright (c) 2014 KIintu Designs Pvt. Ltd. All rights reserved.
//
#import <UIKit/UIKit.h>
#protocol SliderDelegate<NSObject>
- (void)sliderChanged:(id)self;
#end
#interface CustomeTableViewCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UILabel *myCellLabel;
#property (weak, nonatomic) IBOutlet UISlider *mySlider;
#property (weak, nonatomic) IBOutlet UIButton *btnCell;
#property (weak, nonatomic) id <SliderDelegate>sliderDelegate;
- (IBAction)sliderValuechanged:(UISlider *)sender;
#end
for CustomeTableViewCell.m
//
// CustomeTableViewCell.m
// Slider Program
//
// Created by Naeem Shaikh on 21/08/14.
// Copyright (c) 2014 KIintu Designs Pvt. Ltd. All rights reserved.
//
#import "CustomeTableViewCell.h"
#implementation CustomeTableViewCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)awakeFromNib
{
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (IBAction)sliderValuechanged:(UISlider *)sender {
self.myCellLabel.text = [NSString stringWithFormat:#"%d",(NSInteger)sender.value];
//call the custom delegate each time when slider is slided
if([_sliderDelegate respondsToSelector:#selector(sliderChanged:)])
{
[_sliderDelegate sliderChanged:self]; //passing the entire cell itself
}
}
#end
for viewcontroller.h
#import <UIKit/UIKit.h>
#import "CustomeTableViewCell.h"
#interface ViewController : UIViewController <UITableViewDataSource , UITableViewDelegate>{
//NSArray *tableList;
UITableView *mytableview;
int SliderChangeValue;
}
#property (strong , nonatomic) IBOutlet UIView *tableDemo;
#property (strong , nonatomic) NSMutableArray *arrSlider;
#property (strong, nonatomic) NSMutableDictionary *sliderDicValues;
#property (weak, nonatomic) IBOutlet UITableView *myTableView;//add outlet to tableview
#end
for viewcontroller.m
//
// ViewController.m
// Slider Program
//
// Created by Naeem Shaikh on 21/08/14.
// Copyright (c) 2014 KIintu Designs Pvt. Ltd. All rights reserved.
//
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize arrSlider;
#synthesize sliderDicValues;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// tableList = [NSArray arrayWithObjects:
// #"Cell 1",#"Cell 2",#"Cell 3",#"Cell 4",#"Cell 5",
// #"Cell 6",#"Cell 7",#"Cell 8",#"Cell 9",#"Cell 10",
// #"Cell 11",#"Cell 12",#"Cell 13",#"Cell 14",#"Cell 15",
// #"Cell 16",#"Cell 17",#"Cell 18",#"Cell 19",#"Cell 20",
// nil];
arrSlider = [[NSMutableArray alloc]init];
sliderDicValues = [[NSMutableDictionary alloc]init];
//[mytableview registerClass:[CustomeTableViewCell class] forCellReuseIdentifier:#"Cell"];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
//[tableList count]
return 50;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *simpleTableCell = #"Cell";
CustomeTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableCell];
if (cell == nil) {
cell = [[CustomeTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableCell];
}
if([self.sliderDicValues objectForKey:[NSString stringWithFormat:#"%d",indexPath.row]]) //check if there is any slided value is present
{
NSNumber *value = [self.sliderDicValues objectForKey:[NSString stringWithFormat:#"%d",indexPath.row]];
[cell.mySlider setValue:value.integerValue]; //set the slider value
[cell.myCellLabel setText:[NSString stringWithFormat:#"%d",value.integerValue]];//and also label
}
else //set to default values
{
[cell.mySlider setValue:(NSInteger)0];
[cell.myCellLabel setText:#"label"];
}
//add a single target don't add double target to slider
cell.sliderDelegate = self;//set the delegate
return cell;
}
- (void)sliderChanged:(CustomeTableViewCell *)cell
{
NSIndexPath *path = [_myTableView indexPathForCell:cell]; //get the indexpath
if(path)//check if valid path
{
SliderChangeValue = cell.mySlider.value;
[self.sliderDicValues setObject:[NSNumber numberWithInt:SliderChangeValue] forKey:[NSString stringWithFormat:#"%d",path.row]]; //set the value in the dictionary later used in the cellForRowAtIndexPath method
}
// SliderChangeValue = (int)sender.value;
NSLog(#"%d",SliderChangeValue);
}
//dont use it
-(void)customSliderValue:(UISlider *)sender{
// NSString *value =[NSString stringWithFormat:#"%d" ,(int)sender.value];
// NSString *tag = [NSString stringWithFormat:#"%d", (int)sender.tag];
//
// NSLog(#"%# %#",value , tag);
//
// [self.dicSilder setObject:value forKey:#"value"];
// [self.dicSilder setObject:tag forKey:#"tag"];
//
// [self.arrSlider addObject:self.dicSilder];
// NSLog(#"%#",self.arrSlider);
SliderChangeValue = (int)sender.value;
NSLog(#"%d",SliderChangeValue);
}
//this is also put a delegate from the cell like slider , just add the another method in the protocol and perform action, if u don't get just comment i will update the code and u hav t modify this method according to your requirement
-(void)customeBtnClicked:(UIButton *)sender
{
NSString *value =[NSString stringWithFormat:#"%d" ,SliderChangeValue];
NSString *tag = [NSString stringWithFormat:#"%d", sender.tag];
//NSLog(#"%# %#",value,tag);
NSMutableDictionary *dic = [[NSMutableDictionary alloc]init];
[dic setObject:value forKey:#"value"];
[dic setObject:tag forKey:#"tag"];
//NSLog(#"%#",dic);
[arrSlider addObject:dic];
NSLog(#"%#",arrSlider);
NSString *sliderTagAtIndexPath = #"";
//NSString *sliderValueAtindexPath = #"";
for (int i = 0; i < arrSlider.count; i++) {
NSString *strTag = [NSString stringWithFormat:#"%#",[[arrSlider objectAtIndex:i]valueForKey:#"tag"]];
if([strTag isEqualToString:tag])
{
//NSString *strValue = [NSString stringWithFormat:#"%#",[[arrSlider objectAtIndex:i]valueForKey:#"value"]];
sliderTagAtIndexPath = strTag;
//sliderValueAtindexPath = strValue;
}
}
UIAlertView *myAlertView = [[UIAlertView alloc]initWithTitle:#"Clicked"
message:[NSString stringWithFormat:#"Cell : %# Value: %d", sliderTagAtIndexPath ,SliderChangeValue]
//message:[NSString stringWithFormat:#"Cell : %# Value: %#", sliderTagAtIndexPath ,sliderValueAtindexPath]
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[myAlertView show];
}
#end
here is the link for whole app
https://www.mediafire.com/folder/1d4ktomjytb818l,8zcg0zbymee57z8/shared
it is demo for slider in tableview with solution.

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!

Issue Connecting with GCDAsyncSocket with OSX executable

I have the excellent GCDAsyncSocket running perfectly on an iOS app I have developed.
I was just playing around with setting up a Mac OSX command line program that uses the library in a similar way to log to SQLite DB but can't get it to even attempt to connect to host. No errors get generated. The program doesn't crash or anything so don't have an idea about why it's not working. Does anyone have an idea why this won't work?
The console only prints out the following (with no connect/disconnect/read/write logging i.e. the socket delegate methods are not being called):
Attempting to connect to host: 192.168.1.2 on port: 1234 to refresh
Here is quite a bit of the code I am using:
main.m
#import <Foundation/Foundation.h>
#import "LoggerClass.h"
int main(int argc, const char * argv[]) {
#autoreleasepool {
LoggerClass *logger = [[LoggerClass alloc] init];
[logger startLogging];
while (logger.status == 0) {
sleep(1);
continue;
}
return 0;
}
}
LoggerClass.h
#import <Foundation/Foundation.h>
#import "Device.h"
#interface LoggerClass : NSObject <DeviceProtocol>
#property (nonatomic, strong) FMDatabase *database;
#property (nonatomic, strong) NSArray *devices;
#property (nonatomic) int status;
- (void)startLogging;
#end
LoggerClass.m
#import "LoggerClass.h"
#import "FMDatabase.h"
#define kLoggingInProgress 0
#define kLoggingCompleted 1
#implementation LoggerClass
#synthesize database = _database;
#synthesize devices = _devices;
#synthesize status = _status;
- (id)init {
if (self = [super init]) {
self.status = kLoggingInProgress;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *path = [docsPath stringByAppendingPathComponent:#"database.sqlite"];
self.database = [FMDatabase databaseWithPath:path];
Device *d1 = [Device deviceWithName:#"Device 1" address:#"192.168.1.2" delegate:self];
self.devices = [NSArray arrayWithObjects:d1, nil];
}
return self;
}
- (void)startLogging {
for (Device *d in self.devices) {
[d refresh];
}
}
- (void)didUpdateDevice:(Device *)device {
// Insert DB entry code
NSLog(#"%# has finished Logging", device.name);
self.status = kLoggingCompleted; // This would obviously register completed if only 1 device returned but for sake of this test that fine
}
#end
Device.h
#import <Foundation/Foundation.h>
#import "GCDAsyncSocket.h"
#protocol DeviceProtocol;
#interface Device : NSObject
#property (nonatomic, weak) id<DeviceProtocol> delegate;
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSString *address;
#property (nonatomic, strong) GCDAsyncSocket *socket;
+ (Device *)deviceWithName:(NSString *)n address:(NSString *)a delegate:(id<DeviceProtocol>)d;
- (void)refresh;
#end
#protocol DeviceProtocol <NSObject>
#required
- (void)didUpdateDevice:(Device *)device;
#end
Device.m
#import "Device.h"
#define DEVICE_PORT 1234
#implementation Device
#synthesize delegate = _delegate;
#synthesize name = _name;
#synthesize address = _address;
#synthesize socket = _socket;
- (id)initWithName:(NSString *)name andAddress:(NSString *)address andDelegate:(id<DeviceProtocol>)delegate { // Designated Initialiser
if (self = [super init]) {
self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
self.name = name;
self.address = address;
self.delegate = delegate;
}
return self;
}
+ (Device *)deviceWithName:(NSString *)n address:(NSString *)a delegate:(id<DeviceProtocol>)d {
return [[Device alloc] initWithName:n andAddress:a andDelegate:d];
}
#pragma mark - GCD Async Socket Delegate Methods
- (void)socket:(GCDAsyncSocket *)sender didConnectToHost:(NSString *)host port:(UInt16)port {
NSLog(#"Connected to: %#", self.address);
}
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)error {
NSLog(#"Socket for %# disconnected %#.", self.address, error);
if (self.delegate) [self.delegate didUpdateDevice:self];
}
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag {
NSLog(#"socket:didWriteDataWithTag:");
}
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
NSLog(#"socket:didReadData:withTag:");
[self.socket disconnect];
}
- (void)refresh {
if ([self.address length] == 0) { [self.delegate didUpdateDevice:self]; return; }
NSLog(#"Attempting to connect to host: %# on port: %i to refresh", self.address, DEVICE_PORT);
NSError *error = nil;
if (![self.socket connectToHost:self.address onPort:DEVICE_PORT withTimeout:15 error:&error]) NSLog(#"ERROR: %#", error);
NSData *dataToSend;
// Build byte data here to send to device (exact same data works on iOS)
[self.socket writeData:dataToSend withTimeout:10 tag:0];
[self.socket readDataWithTimeout:-1 tag:0];
}
#end
I just re-read your comment and realized what your main() looks like. I think that's where your problem lies. The callbacks are probably sitting in the main dispatch queue but it never gets a chance to execute them. In a Cocoa application, the main queue normally runs as part of the main run loop, but you aren't starting a run loop.
See the dispatch_get_main_queue() documentation.
I think the simplest initial fix is to replace your spin loop with this:
dispatch_main();

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.