Variable not being modified Xcode - objective-c

I'm really lost as to what is happening here.
I am basically trying to pass a variable between two classes but it doesn't even get to that point for one of these variables.
I have two Strings and two buttons declared.
#property (nonatomic, strong) NSString *qm;
#property (nonatomic, strong) NSString *m;
#property (nonatomic, strong) IBOutlet UIButton *mBtn;
#property (nonatomic, strong) IBOutlet UIButton *qmBtn;
I synthesise the strings..
#synthesize qm;
#synthesize m;
Initialise the strings...
- (void)viewDidAppear:(BOOL)animated{
qm = #"0";
m = #"0";
}
And these methods reassign the new variable based on the selected button on the view (I've definitely made sure to link the buttons to their corresponding variables and methods from the view)
- (IBAction)mPressed:(id)sender {
m = #"1";
}
- (IBAction)qmPressed:(id)sender {
qm = #"1";
NSLog(#"This value%#", qm);
}
The NSLog prints the value 1, which is what I want
When the program enters the segue part. Things don't work as planned...
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"Here:%#", qm);
if([m isEqualToString: #"1"]){
QMMPOpViewController *mpOp = [segue destinationViewController];
NSLog(#"test 1:%#",self.qm);
mpOp.qm = self.qm;
mpOp.selectedQuiz = self.selectedQuiz2;
NSLog(#"This value2%#", qm);
NSLog(#"This value3%#", m);
}
else if([qm isEqualToString: #"1"]){
QMMPOpViewController *mpOp = [segue destinationViewController];
NSLog(#"test 2:%#",self.qm);
mpOp.qm = self.qm;
mpOp.selectedQuiz = self.selectedQuiz2;
NSLog(#"This value2%#", qm);
NSLog(#"This value3%#", m);
}
else{
QMSPController *tableVC = [segue destinationViewController];
tableVC.selectedQuiz = self.selectedQuiz2;
}
}
I have changed the value of qm; the NSLog outputs the value 0 instead of the new variable, 1. So therefore ([qm isEqualToString: #"1"]) is never called.
This is so simple yet it still doesn't work despite my attempts to debug the issue. The m value executes fine. Though identical in their means of operation. For some reason the other one does not.
Maybe I'm missing something blatantly obvious or basic. Or if someone could let me know what could possibly be going on here that would be greatly appreciated.

Related

Issue adding to NSMutableArray

I have looked all over the place for anyone who has experienced this issue but have yet to find anything relevant, so I thought I'd ask it myself...
I have a custom object (HitterData) which I will use to populate cells in a UITableView, then two ViewControllers (one is hitterTableViewController, the other is a "detail" view controller labeled "AddPlayerViewController").
The problem is that I can add HitterData objects to the NSMutableArray in my Table VC, but only one, and then when I add another one using the detail view controller, the Mutable array is "reinitialized" and I can again only have one object at a time.
HitterObject:
#implementation HitterData.m
#synthesize hitterName = _hitterName;
#synthesize position = _position;
-(id)initWIthNameAndPosition:(NSString *)hitterName position:(NSString *)position {
if ((self = [super init])) {
self.hitterName = _hitterName;
self.position = _position;
}
return self;
}
HitterTableViewController.h
#import "HitterData.h"
#import "HitterDoc.h"
#import "AddPlayerViewController.h"
#interface HitterTableViewController : UITableViewController
#property (nonatomic, strong) NSMutableArray *hitters;
- (IBAction)backButton:(id)sender;
- (IBAction)addPlayerView:(id)sender;
-(void)addHitterObject:(HitterData *)hitter;
HitterTableViewController.m (only relevant to make this more readable)
#implementation HitterTableViewController
#synthesize hitters = _hitters;
- (void)viewDidLoad {
[super viewDidLoad];
self.hitters = [NSMutableArray array];
}
-(void)addHitterObject:(HitterData *)hitter {
if(_hitters != nil) {
[_hitters addObject:hitter];
} else {
_hitters = [NSMutableArray array];
[_hitters addObject:hitter];
NSLog(#"MutableArray is not valid");
}
}
AddPlayerViewController.h
#interface AddPlayerViewController : UIViewController <UITextFieldDelegate, UINavigationControllerDelegate>
#property (weak, nonatomic) IBOutlet UITextField *nameTextField;
#property (weak, nonatomic) IBOutlet UITextField *positionTextField;
#property (nonatomic) HitterTableViewController *hitterTable;
#property (nonatomic) NSString *hitterName;
#property (nonatomic) NSString *position;
//-(void)addNewHitterToHittersArray:(HitterData *)hitter;
- (IBAction)addPlayerToRoster:(id)sender;
AddPlayerViewController.m
#implementation AddPlayerViewController
#synthesize hitterTable;
- (void)viewDidLoad {
[super viewDidLoad];
hitterTable = [[HitterTableViewController alloc] init];
}
- (IBAction)addPlayerToRoster:(id)sender {
self.hitterName = [self.nameTextField text];
self.position = [self.positionTextField text];
HitterData *hitter = [[HitterData alloc] init];
hitter.hitterName = self.hitterName;
hitter.position = self.position;
[hitterTable addHitterObject:hitter];
ArraySingleton *arrayS = [[ArraySingleton alloc] init];
[arrayS initializeArray];
[arrayS addToHittersArray:hitter];
if (arrayS) {
NSLog(#"arrayS exists in AddPlayerVC");
} else {
NSLog(#"arrayS does not exist");
}
[self performSegueWithIdentifier:#"backToTeamTableViewController" sender:self];
}
Am I missing something here?
Guess based just on the code shown:
Every time you wish to add a player it looks like you create a new AddPlayerView/AddPlayerViewController. In turn that controller creates, in its viewDidLoad, a new HitterTableViewController - which of course has its own empty array. The code should instead be referencing the existing HitterTableViewController.
BTW: The common design pattern is MVC - model, view, controller - consider whether you are in your current situation because you've stored part of your model, the array, in your controller, and maybe both controllers should be referencing a common shared model object containing that array.
BTW: All those #synthesise statements are unneeded. In modern Obj-C synthesis is automatic and you rarely need these statements. Also it is generally recommended to not use the property backing variable directly, and certainly not when storing into the property as this breaks KVO. (There also appears to be a related typo in HitterData.m but as you don't report that as not working it is probably just a typo in your question and not code.)
HTH
AddPlayerViewController should know nothing about HitterTableViewController, return the new HitterData object with a delegate method.
- (IBAction)addPlayerToRoster:(id)sender
{
Hitter *hitter = [[Hitter alloc] init];
hitter.name = [self.nameTextField text];
hitter.position = [self.positionTextField text];
[self.delegate didAddHitter:hitter];
}
Then back in HitterTableViewController
- (void)didAddHitter:(Hitter *)hitter
{
[self.hitters addHitter:hitter];
[self dismissViewControllerAnimated:YES completion:nil];
}

Array loses all values after go trough its own method - Objective C

I have this piece of code below and I'm trying to add Objects(String elements) to an array, problem is that every time I'm out its adding's method, it goes to nil, it doesn't retain the objects.
I know I'm doing wrong, even that I already tried lot of combinations and variations, even with my own constructor _MyArray etc etc, same result... it works, but not further...
Could you help me please?
#interface ArraysModel()
#property (nonatomic, retain) NSMutableArray *MyArray;
#end
#implementation ArraysModel
#synthesize MyArray;
-(void)AddObjectToTheList:(NSString *)object {
if(!MyArray) MyArray = [[NSMutableArray alloc] init];
[MyArray addObject:object];
NSLog(#"%#",self.MyArray);
NSLog(#"Object added %u",[self.MyArray count]);
}
-(NSMutableArray *)ObjectList {
return self.MyArray;
NSLog(#"%#",self.MyArray);
NSLog(#"Object added %u",[self.MyArray count]);
}
#end
The header is like this:
#interface ArraysModel : NSObject
-(void)AddObjectToTheList:(NSString *)object;
And here is my call from my ViewController:
- (IBAction)AddToTheList {
ArraysModel *MyObjectToAdd = [[ArraysModel alloc] init];
[MyObjectToAdd AddObjectToTheList:TextArea.text];
[self.view endEditing:YES];
Well, there's your problem -- you're alloc init'ing a new instance of ArraysModel, and therefore a new array with every call. You need to create a strong reference to your instance, and check for whether it exits, and only init if it doesn't.
In the .h:
#property (strong, nonatomic) ArraysModel *myObjectToAdd;
in the .m:
-(IBAction)AddToTheList {
if (! self.myObjectToAdd) {
self.myObjectToAdd = [[ArraysModel alloc] init];
}
[self.myObjectToAdd AddObjectToTheList:TextArea.text];
[self.view endEditing:YES]
}

Array management help in XCode?

I am creating a program in the iOS SDK in which there is a group of buttons. When a button is clicked, its title is added to an array, and the array is displayed in an assigned label.
When I try to create delete and clear buttons, error messages show up. They show up in the function_builder = function_builder.removeLastObject; and function_builder = function_builder.removeAllObjects; lines of the .m file. The error messages are the same: Assigning to 'NSMutableArray *_strong' from incompatible type 'void'. How do I fix this?
Thank you for any and all help
Here is the .h file:
#import <UIKit/UIKit.h>
#interface SecondViewController : UIViewController
#property (nonatomic,strong) IBOutlet UILabel *equation_field;
#property (nonatomic) NSMutableArray *function_builder;//declare array//
#property(nonatomic, readonly, retain) NSString *currentTitle;//declare button titles//
#end
And here is the .m file:
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
#synthesize equation_field;
#synthesize currentTitle;
#synthesize function_builder;
NSMutableArray *function_builder;//create the array name//
- (IBAction)functionButtonPress:(UIButton *)sender {//code for all buttons except delete and clear//
[function_builder addObject: sender.currentTitle];//when button is pressed, its title is added to the array//
self.equation_field.text = function_builder.description;//the contents of the array appear in the assigned label//
}
- (IBAction)delete:(UIButton *)sender {//create delete button//
function_builder = function_builder.removeLastObject; //ERROR OCCURRING HERE: Assigning to 'NSMutableArray *_strong' from incompatible type 'void'//
}
- (IBAction)clear:(UIButton *)sender{//create clear button//
function_builder = function_builder.removeAllObjects;//ERROR OCCURRING HERE: Assigning to 'NSMutableArray *_strong' from incompatible type 'void'//
}
- (void)viewDidLoad {
function_builder = [[NSMutableArray alloc] init];//initialize array//
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
} else {
return YES;
}
}
#end
Many errors there..
You've assigned the results of this methods (void*) to function_builder which is of kind NSMutableArray. That makes no sense.
In order to manipulate an object, just send a message to it:
[function_builder removeLastObject]; // this will remove the last object of the array
[function_builder removeAllObjects]; // guess what ;)
For the other thing:
self.equation_field.text = [function_builder componentsJoinedByString:#", "]
This will create a string with all objects in array separated by ", " => A, B, C, D
I think that's just how xCode/objective-c converts arrays to strings(Correct me if I'm wrong), so if you want to format it differently you're going to have to iterate through the string and remove the parentheses and commas, which shouldn't be too hard honestly.
The way I'd do it is read through the string and copy the contents unless they are ( ) or , that way your spacing is still correct and you get the filtering effect that you want.

iOS/Objective-C: NSInteger gets lost during simply Coordinates2D object creation

I'm tearing my hair out over this.. I've no idea what's going wrong.
I've created a very simple Coordinates2D class to store two NSInteger values, as well as a string representation for use with NSLog. I'm running this code in the iOS 4.3 iPad simulator bundled with the latest version of xCode.
For some reason the integer values passed to the initX:Y: constructor gets lost. The code below provides Coordinates2D and some code to print an arbitrary float value in its original form, cast as an int, cast as an NSInteger, and then inside the Coordinates2D object.
You should see, as I do, that the value gets lost inside the Coordinates2D constructor; the 'coords.x' argument in NSLog is printed as a random, large integer indicating its value has been lost in memory.
Can anyone help me see why this happens? I can't see what I'm doing wrong.
Many thanks!
Coordinates2D.h
#import <Foundation/Foundation.h>
#interface Coordinates2D : NSObject {
NSInteger x,y;
NSString *asString;
}
#property (nonatomic) NSInteger x,y;
#property (nonatomic, retain) NSString *asString;
-(void)updateStringRepresentation;
-(id)initX:(NSInteger)x Y:(NSInteger)y;
#end
Coordinates2D.m
#import "Coordinates2D.h"
#implementation Coordinates2D
#synthesize x,y,asString;
-(id)initX:(NSInteger)x_ Y:(NSInteger)y_ {
NSLog(#"coords: %i, %i",x_,y_);
if ((self = [super init])) {
self.x = x_;
self.y = y_;
NSLog(#"Coordinates stored %i as %i",x_,self.x);
[self updateStringRepresentation];
}
return self;
}
/*
-(void)setX:(NSInteger)newX {
x = newX;
[self updateStringRepresentation];
}
-(void)setY:(NSInteger)newY {
y = newY;
[self updateStringRepresentation];
}
*/
-(void)updateStringRepresentation {
self.asString = [NSString stringWithFormat:#"%i,%i",x,y];
}
-(void)dealloc {
[asString release];
[super dealloc];
}
#end
Example of problem:
Coordinates2D *coords = [[Coordinates2D alloc] initX:(NSInteger)(202.566223/200.00) Y:0.0f];
NSLog(#"202.566223/200.00 = %f, as int:%i, as NSInteger:%i, as Coordinates2D:%i",
202.566223/200.00, (int)(202.566223/200.00), (NSInteger)(202.566223/200.00), coords.x);
I read awhile ago that you should never use the property accessor in init methods.
I think you want to change:
#property (nonatomic) NSInteger x,y;
to:
#property (nonatomic, assign) NSInteger x,y;
That should fix the error, as it runs fine when I put it in an xcode project.

In Obj-c (xCode) how do I display this string to the text field?

I am trying to make a practice application that takes two entered words (word1, word2) and puts them together to make a compound word. I am very new to this and would like to know the correct way to display these two variables under the action "buttonPressed."
Here's the header file...
#import <UIKit/UIKit.h>
#interface Word_CombinerViewController : UIViewController {
UITextField *word1;
UITextField *word2;
UITextField *display;
UIButton *mashButton;
}
#property (nonatomic, retain) IBOutlet UITextField *word1;
#property (nonatomic, retain) IBOutlet UITextField *word2;
#property (nonatomic, retain) IBOutlet UITextField *display;
#property (nonatomic, retain) IBOutlet UIButton *mashButton;
-(IBAction)textFieldDoneEditing:(id)sender;
-(IBAction)backgroundTap:(id)sender;
-(IBAction)buttonPressed:(id)sender;
#end
And here's the implementation file (.m)...
#import "Word_CombinerViewController.h"
#implementation Word_CombinerViewController
#synthesize word1;
#synthesize word2;
#synthesize display;
#synthesize mashButton;
-(IBAction)textFieldDoneEditing:(id)sender {
[sender resignFirstResponder];
}
-(IBAction)backgroundTap:(id)sender {
[word1 resignFirstResponder];
[word2 resignFirstResponder];
}
-(IBAction)buttonPressed:(id)sender {
NSString *newText = [NSString: #word1, #word2]
display.text = newText;
[newText release]
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[word1 release];
[word2 release];
[display release];
[mashButton release];
[super dealloc];
}
#end
I know this code is probably full of errors, but everyone has gotta start somewhere, right?
Any feedback would be greatly appreciated, thank you!
NSString *newText = [NSString: #word1, #word2]
This code doesn't make any sense. The first part of a message is the receiver, and it won't have any colons in it. The second part is the message itself, i.e. the method name along with any necessary parameters. What you're looking for is:
NSString *newText = [NSString stringWithFormat:#"%#%#", word1, word2];
The -stringWithFormat: method uses a format string (very much like printf()) and a variable number of parameters to fill in the placeholders in the format string.
Also, when you create a string (or any object) using a "convenience method" like this, you shouldn't release it. You didn't retain or alloc or copy it, so it's not your responsibility to release it. You'll want to remove that line from your -buttonPressed method.
Try this:
-(IBAction)buttonPressed:(id)sender {
NSString *newText = [word1.text stringByAppendingString:word2.text]
display.text = newText;
}