This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
EXC_BAD_ACCESS when trying to get iPhone screen dimensions
I have the following code snippet in objective-c that automatically sets some variables to a number of presets. However, on the marked line I get a "Program received signal: EXC_BAD_ACCESS" exception.
What confuses me is that the line above is identical, just with a different value. If line 1 does not throw an exception, why should line 2? What can I do about this?
Thanks in advance!
Sterren
- (IBAction)presetPressed:(id)sender {
if(self.userEnteringNumber) [self enterPressed];
double xVal;
double aVal;
double bVal;
NSString *preset = [sender currentTitle];
if ([preset isEqualToString:#"1"]) {
xVal = 1;
aVal = 2;
bVal = 3;
} else if ([preset isEqualToString:#"2"]) {
xVal = 1.5;
aVal = 2.9;
bVal = 3.0;
} else if ([preset isEqualToString:#"3"]) {
xVal = -1;
aVal = -2;
bVal = -3;
}
[self.variables setValue:[NSNumber numberWithDouble:xVal] forKey:#"x"];
[self.variables setValue:[NSNumber numberWithDouble:aVal] forKey:#"a"];
[self.variables setValue:[NSNumber numberWithDouble:bVal] forKey:#"b"];
self.xVar.text = [NSString stringWithFormat:#"= %#", xVal];
self.aVar.text = [NSString stringWithFormat:#"= %#", aVal]; //EXC_BAD_ACCESS here
self.bVar.text = [NSString stringWithFormat:#"= %#", bVal];
[self calculateResult];
}
xVal, aVal, bVal are all primitive doubles, but yet your string format is looking for an object via %#.
try replacing %# with %f (or %g if you prefer scientific notation):
self.xVar.text = [NSString stringWithFormat:#"= %f", xVal];
self.aVar.text = [NSString stringWithFormat:#"= %f", aVal];
self.bVar.text = [NSString stringWithFormat:#"= %f", bVal];
Replace your formatting strings #"= %#" with #"= %g".
Your formatting string was assuming that the given parameter value would be an object instance (%#) but you supplied a scalar double value which is not an object instance but of a primitive type.
Related
The error is a EXC_BAD_ACCESS, which is typically a bad pointer of some sort, but the problematic _rawText property is created in the same scope where it fails. Here's the code from the command line tool. The only difference between this and the app version is the URL for the file, and via NSLog I've verified that both files are being read and have the same length, as they should.
Here's the updated code, which sometimes runs and sometimes fails. I'm using getters and setters for rawText this time around, instead of accessing _rawText directly.
-(void)loadDictionary {
NSURL *cedict_url = [NSURL fileURLWithPath:#"cedict_ts.txt"];
NSLog(#"cedict_url is %#", cedict_url);
NSError *loadError;
[self setRawText:[NSString stringWithContentsOfURL:cedict_url encoding:NSUTF8StringEncoding error:&loadError]];
// _rawText = [NSString stringWithContentsOfURL:cedict_url encoding:NSUTF8StringEncoding error:&loadError];
if (_rawText == nil) NSLog(#"No _rawText object");
if (loadError == nil) NSLog(#"No error from stringWithContentsOfURL:");
if (loadError) {
NSLog(#"%#", loadError);
return;
} else {
// This next line fails with the error "Thread 1: EXC_BAD_ACCESS (code=1, address=0x20)
NSLog(#"Dictionary loaded, string of length %lu", (unsigned long)[[self rawText] length]);
// 0x20 is kind of small for an NSString's memory location
}
NSArray *rawLines = [[self rawText] componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
NSLog(#"Broke file into %lu lines", (unsigned long)[rawLines count]);
NSLog(#"First 10 lines are...");
for (int iLine = 0; iLine < 10; iLine++) {
NSString *theLine = [rawLines objectAtIndex:iLine];
NSLog(#"Line %d, %lu characters: %#", iLine, theLine.length, theLine);
}
NSMutableArray *singleHanCharacterLines = [NSMutableArray arrayWithCapacity:[rawLines count]];
for (NSInteger i=0; i<[rawLines count]; i++) {
NSString *line = [rawLines objectAtIndex:i];
NSComparisonResult hasHash = [line compare:#"#" options:NSCaseInsensitiveSearch range:NSMakeRange(0, 1)];
NSComparisonResult isSpace = [line compare:#" " options:NSCaseInsensitiveSearch range:NSMakeRange(1, 1)];
BOOL nonComment = hasHash != NSOrderedSame;
BOOL oneHanLine = isSpace == NSOrderedSame;
if (nonComment & oneHanLine) [singleHanCharacterLines addObject:line];
}
NSLog(#"Found %lu lines starting with a single Han character", (long int)[singleHanCharacterLines count]);
dLines = [NSArray arrayWithArray:singleHanCharacterLines];
}
The NSLog that prints the length of _rawText gives the same result for both versions.
Are there some settings that I need to change, or some additional techniques I've forgotten? Thanks!
I have stored a value 1/129600.0 in a plist as a string.
I am able to retrieve it as a string but when i am trying to convert it as a double i am getting it as 1.0.I have also tried CFString
NSString *value = [[self array]objectAtIndex:m];
double a = [value doubleValue];
NSLog(#"%#",value);
NSLog(#"%f",a);
and in log the returned values are
1/129600.0 and 1.0
This code works fine, I tried it in xCode:
NSString *equation = [[self array]objectAtIndex:m];
NSExpression *result = [NSExpression expressionWithFormat:equation];
NSNumber *a = [result expressionValueWithObject:nil context: nil];
NSLog(#"%#",result);
NSLog(#"%.10f",[a doubleValue]);
I guess 1/129600.0 is not a valid number.
Try to create an expression and create an NSNumber from it:
NSString *equation = [[self array]objectAtIndex:m];
NSNumber *a = [[NSExpression expressionWithFormat:equation] expressionValueWithObject:nil context:nil];
double a = [result doubleValue];
NSLog(#"%f", a);
1/129600.0 is not a valid representation for a number in most programming languages, including ObjC. You need to parse the string and interpret it yourself.
Try this
NSString *value = [[self array]objectAtIndex:m];
NSArray *arr = [value componentsSeparatedByString:#"/"];
double a;
if ([arr count] == 2)
{
a = [arr objectAtIndex:0]/[arr objectAtIndex:1];
}
NSLog(#"%#",value);
NSLog(#"%f",a);
What is causing the 'Expected identifier' error on line 3 below?
-(IBAction)changeGreeting:(id)sender {
self.userName = self.textField.text;
float amount = [[self.textField.text] floatValue]; **! Expected identifier**
// float amount = [[self.userName] floatValue];
NSString *nameString = self.userName;
if ([nameString length] == 0) {
nameString = #"World";
}
NSString *greeting = [[NSString alloc] initWithFormat:#"Hello, %#!", nameString];
self.label.text = greeting;
}
Can I do the text conversion to float, double the value & display it within this same button action method?
I am new to OOP programming. Any tips greatly appreciated.
Walter
Your problem is:
[self.textField.text]
You do not need to put the [ ] because you are not calling a method, you was supposed to just call it this way:
[self.textField.text floatValue]
You will just need to use the [ ] when you want to call a method.
I have got a for loop where 9 hexagons (hexagon1 through hexagon9) have to be created... But I cannot use hexString as the name of the Sprite because it is a NSString, right ? So how would I make it right ?
hexString [<- I want the for loop to generate "hexagon1", then "hexagon2" and so on instead of the NSString] = [self createHexagon:ccp(xVal,yVal) :i];
int hexCount = [[[itemPositions valueForKey:myString]valueForKey:#"hexposition"] count];
for (int i=1;i<=hexCount;i++){
NSString *hexString = [NSString stringWithFormat:#"hexagon%d",i];
NSNumber *generatedXVal = [[[[itemPositions valueForKey: myString ]valueForKey:#"hexposition"] valueForKey: hexString]valueForKey: #"xVal"];
int xVal = [generatedXVal integerValue];
NSNumber *generatedYVal = [[[[itemPositions valueForKey: myString ]valueForKey:#"hexposition"] valueForKey: hexString ]valueForKey: #"yVal"];
int yVal = [generatedYVal integerValue];
hexString = [self createHexagon:ccp(xVal,yVal) : i];
NSLog(#"%#", hexString);
}
That would be impossible as you didn't declare the variable. A work around for this would be using an NSArray and saving your data on to the array instead of making a list of variables.
Use NSMutableDictionary.
for (int i=1;i<=hexCount;i++){
NSString *hexString = [NSString stringWithFormat:#"hexagon%d",i];
CCSprite *sprite = [self doSomethingToGetSprite];
[mutableDictionary setObject:sprite forKey:hexString];
}
Later you can iterate over all the sprites in the dictionary using:
for (NSString *key in mutableDictionary) {
CCSprite *sprite = [mutableDictionary objectForKey:key];
[self doStuffWithSprite:sprite];
}
By the way, why are you overwriting hexString that you assign here:
NSString *hexString = [NSString stringWithFormat:#"hexagon%d",i];
With the one here:
hexString = [self createHexagon:ccp(xVal,yVal) : i];
And that method call is an obvious syntax error with the dangling : i part there.
can you use NSSelectorFromString?
I have the following code snippet in my Xcode:
NSString *digit [[sender titlelabel] text];
NSLog([digit]);
I tried to build the application and am getting the following warning message for the line NSLog([digit]);
Warning: Format not a string literal and no format arguments
Can you advise me how I can resolve this warning message? What does the message actually mean?
Try this piece of code:
NSString *digit = [[sender titlelabel] text];
NSLog(#"%#", digit);
The message means that you have incorrect syntax for using the digit variable. If you're not sending it any message - you don't need any brackets.
Use NSLog() like this:
NSLog(#"The code runs through here!");
Or like this - with placeholders:
float aFloat = 5.34245;
NSLog(#"This is my float: %f \n\nAnd here again: %.2f", aFloat, aFloat);
In NSLog() you can use it like + (id)stringWithFormat:(NSString *)format, ...
float aFloat = 5.34245;
NSString *aString = [NSString stringWithFormat:#"This is my float: %f \n\nAnd here again: %.2f", aFloat, aFloat];
You can add other placeholders, too:
float aFloat = 5.34245;
int aInteger = 3;
NSString *aString = #"A string";
NSLog(#"This is my float: %f \n\nAnd here is my integer: %i \n\nAnd finally my string: %#", aFloat, aInteger, aString);
Why do you have the brackets around digit?
It should be
NSLog("%#", digit);
You're also missing an = in the first line...
NSString *digit = [[sender titlelabel] text];
The proper way of using NSLog, as the warning tries to explain, is the use of a formatter, instead of passing in a literal:
Instead of:
NSString *digit = [[sender titlelabel] text];
NSLog(digit);
Use:
NSString *digit = [[sender titlelabel] text];
NSLog(#"%#",digit);
It will still work doing that first way, but doing it this way will get rid of the warning.
type : BOOL
DATA (YES/NO) OR(1/0)
BOOL dtBool = 0;
OR
BOOL dtBool = NO;
NSLog(dtBool ? #"Yes" : #"No");
OUTPUT : NO
type : Long
long aLong = 2015;
NSLog(#"Display Long: %ld”, aLong);
OUTPUT : Display Long: 2015
long long veryLong = 20152015;
NSLog(#"Display very Long: %lld", veryLong);
OUTPUT : Display very Long: 20152015
type : String
NSString *aString = #"A string";
NSLog(#"Display string: %#", aString);
OUTPUT : Display String: a String
type : Float
float aFloat = 5.34245;
NSLog(#"Display Float: %F", aFloat);
OUTPUT : isplay Float: 5.342450
type : Integer
int aInteger = 3;
NSLog(#"Display Integer: %i", aInteger);
OUTPUT : Display Integer: 3
NSLog(#"\nDisplay String: %# \n\n Display Float: %f \n\n Display Integer: %i", aString, aFloat, aInteger);
OUTPUT :
String: a String
Display Float: 5.342450
Display Integer: 3
http://luterr.blogspot.sg/2015/04/example-code-nslog-console-commands-to.html
NSLog(#"%#", digit);
what is shown in console?
NSLog([digit]); // [] are the messages in Objective-C, just like methods or functions in other programming languages
Since you just need to print the value of 'digit'
Either you can call -
NSLog(digit); // A warning would occur - Format string is not a string literal (potentially insecure)
OR
NSLog(#"%#",digit]); // But if you use %# to reference the object, the warning will go away.
Both the methods will work but the second one is the right way of logging to console.