objective c and xcode assigning value to label coming from a NSInteger type variable - iphone

It's me again, I've been struggling with this for the past hour and a half and can't seem to find a good way of implementing this. I'm basically trying to display results on a label on clicking of a button. (Just starting out with xcode so I'm not sure if that's the right term for that action). Anyway, here's my code and the method on my controller: I have
#interface Match : NSObject{
}
#property NSInteger *Id;
#property NSString *fighter1, *fighter2;
- (id) initWithWCFId:(NSInteger)matchId bracketId:(NSInteger)bracketId;
#end
#implementation Match
- (id) initWithWCFId:(NSInteger)matchId bracketId:(NSInteger)bracketId{
self = [self init];
if(self){
self.Id = &(matchId);
self.fighter1 = #"Person 1";
self.fighter2 = #"Person 2";
}
return self;
}
#end
--- controller ---
#interface ViewController : UIViewController{
/*IBOutlet UITextField *txtFieldBracketId;
IBOutlet UITextField *txtFieldMatchId;*/
}
#property (weak, nonatomic) IBOutlet UITextField *txtFieldBracketId;
#property (weak, nonatomic) IBOutlet UITextField *txtFieldMatchId;
- (IBAction)btnSubmit:(id)sender;
#end
--- implementation
- (IBAction)btnSubmit:(id)sender {
#autoreleasepool {
Match *match = [[Match alloc]initWithWCFId:[_txtFieldMatchId.text integerValue] bracketId:[_txtFieldBracketId.text integerValue]];
self.lblMatchId.text = [[NSString alloc] initWithString:[NSNumber numberWithInt:match.Id]];
self.lblFighter1.text = [[NSString alloc] initWithString:match.fighter1];
self.lblFighter2.text = [[NSString alloc] initWithString:match.fighter2];
}
}
I basically have two text boxes.
Now when I click the button it'll get the value for those text boxes and then displays the data it got based off of those inputs. It'll then display the three following data:
Id, Fighter1 and Fighter2.
So what's happening is, when I click the button, the whole thing stops and gives me this error:
NSInvalidArgumentException', reason: '-[__NSCFNumber length]:
unrecognized selector sent to instance 0x74656e0'
* First throw call stack: (0x1c90012 0x10cde7e 0x1d1b4bd 0x1c7fbbc 0x1c7f94e 0xae4841 0x2891 0x10e1705 0x18920 0x188b8 0xd9671 0xd9bcf
0xd8d38 0x4833f 0x48552 0x263aa 0x17cf8 0x1bebdf9 0x1bebad0 0x1c05bf5
0x1c05962 0x1c36bb6 0x1c35f44 0x1c35e1b 0x1bea7e3 0x1bea668 0x1565c
0x23dd 0x2305) libc++abi.dylib: terminate called throwing an exception
Now I'm not sure if 1. The way I designed my class is correct, using "NSInteger" for the property id. or
2. Assigning the Id integer to string (edit box) is wrong.

Two things:
The property should not be pointer type, so it should be #property NSInteger Id; and in init it should be just self.Id = matchId;
Make it to string by using [NSString stringWithFormat:#"%d", match.Id]

In addition to the issues with your Id property, the crash is coming from this:
self.lblMatchId.text = [[NSString alloc] initWithString:[NSNumber numberWithInt:match.Id]];
You are trying to pass an NSNumber object as the argument to the initWithString: method. But this method expects an NSString value, not an NSNumber.
Update the three lines to:
self.lblMatchId.text = [[NSString alloc] initWithFormat:#"%d", match.Id];
self.lblFighter1.text = match.fighter1;
self.lblFighter2.text = match.fighter2;
I'm assuming match.fighter1 and match.fighter2 are NSString properties.

Related

Unrecognized selector sent to instance?

I have seen that a few others have had this problem as well.
I'm trying to follow a tutorial online that shows how to create animated pins on a MapView.
I have implemented the code as shown in the tutorial and the project builds fine except I receive this exception:
-[MKPointAnnotation iconN]: unrecognized selector sent to instance
I have a subclass of 'MKPinAnnotationView' and in the .m file I create this method:
- (void)setAnnotation:(id<MKAnnotation>)annotation {
[super setAnnotation:annotation];
//Place *place = [[Place alloc] init];
Place *place = (Place *)annotation;
//The following line is where the program sends "SIGABRT"
icon = [UIImage imageNamed:[NSString stringWithFormat:#"pin_%d.png", [place.iconN intValue]]];
[iconView setImage:icon];
}
Here are a few parts from my "model" which is called Place.h/.m.
Here is where I create the property for 'iconN'.
#property (retain, nonatomic) NSNumber *iconN;
And here I synthesize it:
#synthesize iconN = _iconN;
Any help is greatly appreciated.
EDIT:
Here is the Place.h and Place.m
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
#interface Place : NSObject <MKAnnotation> {
CLLocationCoordinate2D coordinate;
NSString *title;
}
#property (retain, nonatomic) NSNumber *iconN;
#property (nonatomic, copy) NSString *title;
#property (nonatomic) CLLocationCoordinate2D coordinate;
- (id)initWithLong:(CGFloat)lon Lat:(CGFloat)lat iconNumber:(NSNumber *)iconNumber;
#end
And the Place.m
#import "Place.h"
#implementation Place
#synthesize coordinate;
#synthesize iconN = _iconN;
#synthesize title;
- (id)initWithLong:(CGFloat)lon Lat:(CGFloat)lat iconNumber:(NSNumber *)iconNumber {
self = [super init];
if (self) {
coordinate = CLLocationCoordinate2DMake(lat, lon);
self.iconN = iconNumber;
}
return self;
}
- (NSString *)title {
return [NSString stringWithFormat:#"Bus: %d", [self.iconN intValue]];
}
- (NSString *)subtitle {
return [NSString stringWithFormat:#"bus[%d] from database.", [self.iconN intValue] - 1];
}
#end
You cannot convert a MKAnnotation to a Place just by casting it. This line is wrong.
Place *place = (Place *)annotation;
You should post your Place.h and Place.m files if you're still stuck. You need to either set the iconN property on a new Place object, or create an init method in the Place class that accepts the MKAnnotation object as a parameter and sets it own internal values accordingly.
In the line
Place *place = (Place *)annotation;
has the variable place of annotation variable class (MKPointAnnotation), you are not able to bring the master class variable to a subclass in this way. Instead you'll have to make a constructor for Place from MKPointAnnotation and perform a check in the setAnnotation method that annotation is of MKPointAnnotation.
You are sending the message to the annotation but you seem to have subclasses the annotation view.
Posting as an answer what was originally just a comment:
I'm not familiar with the MapKit, but the thing that sticks out for me in this: -[MKPointAnnotation iconN]: unrecognized selector sent to instance is that the class is MKPointAnnotation. So the annotation you're receiving isn't actually a Place object, it's an MKPointAnnotation object - you can't just cast to Place. I suspect the root of your problem is where you create your annotation object in the first place.

Storing and opening data in a variable

I'm making an app that calculates certain things.
I need it to be able to take the input from the first textfields, for example 4+4 and save the result in a variable.
In the second text fields there could be 8+8 for example, and the result of that will also be saved into a variable (possibly the same).
Third row of textfields could yield more numbers etc, etc..
In the end there will be a button "Calculate" for example. And that will take the results from first, second, third etc textfields and calculate all of those together and output the end result.
The calculations are of course more advanced than this, but I just need the basic/simple idea of how to do this.
There is no need for saving the data to a file just now, it should just be in the app while the other textfields are being filled.
For 0x8badf00d:
Header.
#interface UnitConverterViewController : UIViewController {
NSMutableArray *calculationsArray;
UITextField *m1Text;
UITextField *m2Text;
}
#property (nonatomic, retain) IBOutlet UITextField *m1Text;
#property (nonatomic, retain) IBOutlet UITextField *m2Text;
#property (nonatomic, retain) IBOutlet NSMutableArray *calculationsArray;
#end
Implementation:
#implementation UnitConverterViewController
#synthesize m1Text, m2Text, calculationsArray;
#synthesize resultTotal = _resultTotal;
-(id)init {
if(self = [super init]){
calculationsArray = [[NSMutableArray alloc] init];
}
}
- (void)compute{
NSString* sumString = [NSString stringWithFormat:#"%d",[m1Text.text intValue]+[m2Text.text intValue]];
[calculationsArray addObject:sumString];
}
-(IBAction)calculate{
int total=0;
for(NSString* sumStr in calculationsArray){
total = total+[sumStr intValue];
}
NSLog(#"Total: %d", total);
[calculationsArray release], calculationsArray = nil;
}
I must be doing something wrong, and I know I need a way to output this, a label and such. But for now I need to know if what I've done so far is correct, and what the best way of outputting it would be.
You should declare the variables to store the results in your header file, these are than accessible from anywhere in your .m file, the same goes for your text fields.
For example:
Calculator.h
#interface Calculator: SuperclassName{
UITextField *_fldOne;
UITextField *_fldTwo;
UITextField *_fldThree;
UITextField *_fldFour;
int resultOne;
int resultTwo;
int _resultTotal;
}
#property(nonatomic, readonly) int resultTotal;
- (void) calculate;
#end
Calculator.m
#implementation Calculator
#synthesize resultTotal = _resultTotal;
- (void) calculate{
resultOne = [_fldOne.text intValue] * [_fldTwo.text intValue];
resultTwo = [_fldThree.text intValue] / [_fldFour.text intValue];
totalResult = resultOne + resultTwo;
}
#end
In this example resultOne and Two, and all the textfields are available throughout your class to work with, the totalResult is set as a readonly property and synthesized to create a getter automaticaly (which returns the value stored in _totalResult because of synchronizing like totalResult = _totalResult) as so it is available to read from outside the class.
As long as it all happens on one screen it should be more than enough, but of course you could make an NSDictionary or NSArray but that seems unnecessary here.
Hope this helps
Save the result to array. Lets say you have NSMutableArray* calculationsArray;//iVar
//initialize calculationsArray in init method
-(id)init
{
if(self = [super init])
{
calculationsArray = [[NSMutableArray alloc] init];
}
}
- (void)compute
{
NSString* sumString = [NSString stringWithFormat:#"%d",[textField1.text intValue]+[textField2.text intValue]);
[calculationsArray addObject:sumString];
}
- (IBAction)calculate
{
int total=0;
for(NSString* sumStr in calculationsArray)
{
total = total+[sumStr intValue];
}
NSLog(#"Total: %d",total);
[calculationsArray release],calculationsArray = nil;
}

Problems with getting data from a class

I guess this is quite basic, but I am struggling with getting data (in this case a simple string) from a class.
My class is quite simple; it looks like this:
#interface myBook : NSObject {
NSString *titleName;
NSString *titleColour;
}
And then I have all the #property and #synthesise calls. I import this (#import myBook.h) in my viewController, where I want to add books to my library. So I have this set of variables to control my library:
NSMutableArray *myLibrary;
NSUInteger currentBookNumber;
myBook *currentBook;
and:
#property (nonatomic, retain) NSMutableArray *myLibrary;
#property (nonatomic, assign) NSUInteger currentBookNumber;
#property (nonatomic, readonly) NoteBook *currentBook;
I then set up my library like so:
-(void) setupLibrary {
myBook *newBook = [[myBook alloc] init];
newBook.titleName = #"Test";
newBook.titleColour = #"orange";
[myLibrary addObject:newBook];
[myLibrary addObject:newBook];
[myLibrary addObject:newBook];
currentBookNumber = 0;
}
In order to get data from the current book I have the following method:
-(NmyBook *) currentBook {
myBook *thisBk = [self.myLibrary
objectAtIndex:self.currentBookNumber];
return thisBk;
}
Now my problem is that if I want to get data from myLibrary and call this in my viewDidLoad, I will only get nil for the title... where did I go wrong?
- (void)viewDidLoad {
[self setupLibrary];
NSLog(#"TitleName:%#", currentBook.titleName);
Issues I see:
Number 1:
I hope the currentBook method return type is a typo. I'm seeing a -(NmyBook *)... shouldn't that be a - (myBook *)?
Number 2:
You never initialized the currentBook object. Before you call the NSLog, you should go
currentBook = [self currentBook];
Where [self currentBook] calls the currentBook method and sets the returned object as the currentBook object.
Finally, try not having the same names for variables and methods :)
Hope that helps.
You have to use self.currentBook.titleName. currentBook.titleName won't trigger your accessor.
By the way, your setupLibrary is leaking. You'll want to add [newBook release] after the last [myLibrary addObject:newBook] call.
You had called one property currentBook and one method currentBook :
Normally it works but you should call the method getCurrentBook;
and the right to access to a property in his class is to use :
[self.theProperty method];
Use :
newBook.titleName = [NSString stringWithFormat:#"Test"];
newBook.titleColor = [NSString stringWithFormat:#"Orange"];
After you can call :
NSLog(#"TitleName:%#", self.currentBook.titleName);

CFString isNaturallyRTL - message sent to deallocated instance

I already googled for "CFString isNaturallyRTL" with 0 results.
these are my classes:
//in .H
#interface myViewController : UIViewController {
UITextField *from;
UITextField *to;
NSString *fromText;
NSString *toText;
}
#property (nonatomic, retain) NSString* fromText;
#property (nonatomic, retain) NSString* toText;
#property (nonatomic, retain) UITextField *from;
#property (nonatomic, retain) UITextField *to;
//in .m
#synthesize from, to;
#synthesize fromText, toText;
viewDidLoad(...) {
fromText = #"Roma";
toText = #"Lecce";
}
- (void) drawRoute {
if ( ([[from text] length] > 2) && ([[to text] length] > 2) )
{
fromText = from.text;
toText = to.text;
[...]
}
}
Now, i have a view that open on button touch tha contains two text boxes and a button. Like this.
- (void) drawRouteTextboxes {
from = [[UITextField alloc] initWithFrame: [...] ];
from.text = fromText;
from.delegate = self;
[ctr.view addSubview:from];
[from release];
to = [[UITextField alloc] initWithFrame: [...] ];
[...]
[searchButton addTarget:self action:#selector(drawRoute) forControlEvents: UIControlEventTouchUpInside];
}
It's all correct, compile and run.
First time that i click drawRouteTextboxes, it opens my view with default text setted ("Roma" and "lecce").
Second time, i open the view, edit textfield and call drawRoute. It's ok.
The third time that i call drawRouteTextboxes it return me this runtime error:
*** -[CFString _isNaturallyRTL]: message sent to deallocated instance 0x3a8d140
I don't know where is the problem...
Someone know a solution?
It's the first time that i see this error!
thanks,
Alberto.
It's all correct, compile and run.
If it was all correct, it would run without error. ;)
This looks suspect:
fromText = from.text;
toText = to.text;
If from.text and to.text are returning either autoreleased objects or objects that are later released, then the above doesn't retain the strings and could easily lead to an over-release problem as you are seeing.
Use self.fromText = from.text; instead.
Note that NSString* properties should almost always be copy and not retain.

Problem with sharing variables between views - missing something?

I know im missing something but my friend and I can figure out what.
Firstly.. I have two .hs and .ms that I'd like to share data between - two view controllers
In the first .h i have this - that makes the variables and properties them
//top half of .h
//Passing to Submit Page
NSMutableString *messageString;
NSInteger theirTime;
}
#property (nonatomic, readwrite) NSInteger theirTime;
#property (nonatomic, retain, readwrite) NSMutableString *messageString;
/actions
#end
Then in the respective .m - sythesize them
#synthesize messageString, theirTime;
then from the new .h and .h i need to acces them.. so In view did load i do this
- (void)viewDidLoad {
messageString = [[NSMutableString alloc] init];
MemoryViewController *controller = [[MemoryViewController alloc] init];
timeInSeconds = controller.theirTime;
NSLog(#"Time = %d", timeInSeconds);
messageString = controller.messageString;
NSLog(#"Message - %#", messageString);
[controller release];
NSUserDefaults *HighScore = [NSUserDefaults standardUserDefaults];
bestTime.text= [NSString stringWithFormat:#"Best Time:%d", [HighScore integerForKey:#"integerKey"]];
currentTime.text = [NSString stringWithFormat:#"Current Time:%d", timeInSeconds];
[super viewDidLoad];
}
and at the top
#import "MemoryViewController.h"
and now the .h to show you all what the variables are
IBOutlet UILabel *bestTime;
IBOutlet UILabel *currentTime;
int timeInSeconds;
NSMutableString *messageString;
So. In short - I made variables made properties, and synthesized them, then in the view i make an instance of the other VC, then try use them to do things
Log out put
2010-04-15 20:53:09.105 Memory[3538:207] Time = 0
2010-04-15 20:53:09.107 Memory[3538:207] Message - (null)
Any ideas guys would be great... if you need more code/ less code just say.. ive tried other blogs but they all do it with app delegates.. and i dont like global variables.
Cheers
Sam
You initialised a new MemoryViewController instance in your -viewDidLoad, so of course all of its instance variables are 0 or nil. If you already have a MemoryViewController that you need to get the properties from, you need to reference that instance instead of creating a new one.