I'm literally going crazy whit these six rows of code.
NB: nome and prezzo are 2 textFields
NSString *itemName = (NSString *) [rowVals objectForKey:#"name"];
NSString *itemPrice = (NSString *) [rowVals objectForKey:#"price"];
nome.text = itemName;
nome.userInteractionEnabled = YES;
prezzo.text = itemPrice;
prezzo.userInteractionEnabled = YES;
Don't know why when itemPrice is copied in one of those label, the program go in SIGABRT.
Instead if I try to read the content with an NSLog(#"%#",itemPrice); it return the exact value, so it means that is a valid NSString.
The only solution I found is passing through a NSNumber:
NSNumber *itemPrice = (NSNumber *) [rowVals objectForKey:#"price"];
prezzo.text = [[NSString alloc] initWithFormat:#"%#", itemPrice];
There is another way to use directly the NSString?
Probably the value in the #"price" field is NSNumber, and not an NSString. The NSLog method will still provide a correct result, since %# is used for any NSObject subclass, not just NSString.
How about this:
NSString *itemPrice = [[rowVal objectForKey:#"price"] stringValue];
prezzo.text = itemPrice;
The problem might be the object type returned by [rowVals objectForKey:#"price"]. When you place the (NSString *) cast before the method call, you're telling the compiler what type of object is returned, but not actually converting it into an NSString. The line you use below does convert from NSNumber (or whatever other object) to a string: [[NSString alloc] initWithFormat:#"%#", itemPrice]
You might be storing NSNumber's object in NSDictionary instead of NSString.
There could be 2 ways: one would be to convert NSNumber to NSString while adding it to dictionary or the other way would be to convert NSNumber to NSString while assigning it to "itemName".
you may do the conversion for second option like:
NSString *itemPrice = [[rowVals objectForKey:#"price"]stringValue];
Related
What is the difference of notificationIdToCancle1 and notificationIdToCancle2 in the code below:
NSDictionary* parameters = (NSDictionary* )parametersObject;
if (parameters != nil) {
NSString* notificationIdToCancle1 = (NSString* )[parameters objectForKey:#"id"];
NSString *notificationIdToCancle2 = [NSString stringWithFormat:#"%#",[parameters valueForKey:#"id"]];
}
Shouldn't both contain the same value?
NSString* notificationIdToCancle1 = (NSString* )[parameters objectForKey:#"id"];
This line is grabbing the object in the dictionary, casting it to an NSString whether it is or isn't.
[NSString* stringWithFormat:#"%#",[parameters valueForKey:#"id"]];
This line, I think you have a mistake, you probably don't want the first '*'. You also probably want to call 'objectForKey:' rather than 'valueForKey:'. objectForKey: will return the entry in the dictionary, while valueForKey: will use Key Value Coding to return a value.
So:
[NSString stringWithFormat:#"%#",[parameters objectForKey:#"id"]];
This takes the object in the dictionary, runs 'description' on it which returns an NSString instance. So you definitely get an NSString instance out of it.
When I make:
NSString x = #"test"
How do I edit it so that it becomes "testing"?
And when I put:
NSMutableString x = [[NSMutableString alloc] initWithString:#"test"];
There is an error that says:
Initializer element is not a compile-time constant.
Thanks
When declaring NSMutableString, you missed the asterisk:
NSMutableString *x = [[NSMutableString alloc] initWithString:#"test"];
// Here --------^
With a mutable string in hand, you can do
[x appendString:#"ing"];
to make x equal testing.
You do not have to go through a mutable string - this will also work:
NSString *testing = [NSString stringWithFormat:#"%#ing", test];
You need to declare your NSString or NSMutableString as *x. These are pointers to objects.
To change a string in code is quite easy, for example:
NSString *test = #"Test";
test = [test stringByAppendingString:#"ing"];
And the value in test will now be Testing.
There are a lot of great NSString methods, both instance and class methods, for manipulating and working with strings. Check the documentation for the complete list!
if you want to add multiple or single strings to an existing NSString use the following
NSString *x = [NSString stringWithFormat:#"%#%#", #"test",#"ing"];
Someone use the following to initialize the NSstring
NSString *astring = [[NSString alloc] init];
I am wondering why not just use
NSString *atring = nil or NSString *astring = #""
There is no semantic difference between NSString *astring = [[NSString alloc] init]; and NSString *astring = #""; - but NSString *astring = nil; is completely different. The first two produce a reference to an immutable string value, the last indicates the absence of a value.
Whether the various ways of generating an zero-length string produce different objects is entirely an implementation detail. The code:
NSString *a = [[NSString alloc] init];
NSString *b = [NSString new];
NSString *c = #"";
NSString *d = [NSString stringWithString:#""];
NSLog(#"%p, %p, %p, %p, %p", a, b, c, d, #""); // %p = print the value of the reference itself
outputs (the exact values will vary):
0x7fff7100c190, 0x7fff7100c190, 0x1000028d0, 0x1000028d0, 0x1000028d0
showing only 2 zero-length string objects were created - one for #"" and one for alloc/init. As the strings are immutable such sharing is safe, but in general you should not rely on it and try to compare strings using reference comparison (==).
NSString *atring = nil
is different -- it's a nil pointer, not an empty string.
NSString *astring = #""
is almost the same, if you change it to something like
NSString* astring=[#"" retain];
It's one of the things that "don't matter"; he or she simply used one way. Probably for no particular reason at all.
NSString *atring = nil; is simply setting the pointer to nil and does nothing other than ensure that pointer is set to nil;
NSString *astring = #""; is a shorthand literal and is the equivalent of [NSString stringWithString:#""];
On another point I don't know why you would want to initialize a string to nothing if its not mutable since you won't be able to change it later without overriding it.
I've put NSNumber object into NSDictionary object, and then pop and assign it to a variable declared as NSString instance.
NSString *test;
NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1000] forKey:#"key"];
test = [dict valueForKey:#"key"];
NSLog(#"%#, type of %#", test, NSStringFromClass([test class]));
return 0;
After running the above code, I've found that the type of test, declared as (NSString *) is __NSCFNumber. Why did it happen and why compiler did give no warning or errors?
Do I have to NSString constructor, such as NSStringWithFormat..., in order to keep test as NSString's instance?
The reason this did not fail or warn you is because valueForKey: returns an object of type id which you can assign to any Objective-C type. You need to be aware of what type of value you are getting back from your collections to safely use them. In this case you know it contains an NSNumber so you should expect an NSNumber and if you need a string you will need to do the proper conversions.
NSNumber *test = [dict valueForKey:#"key"];
NSLog(#"%#, type of %#", test, NSStringFromClass([test class]));
//If you need a string
NSString *testStr = [test stringValue];
I have a string array as such:
NSArray *names;
names = [NSArray arrayWithObjects:
#"FirstList",
#"SecondList",
#"ThirdList",
nil];
I'm trying to assign an element of this string array to a string variable as such:
NSString *fileName = names[0]; // "Incompatible types in initialization"
or with casting
NSString *fileName = (NSString)names[0]; // "Conversion to non-scalar type requested"
I'm trying to do this, so I can use the string in a method that takes a string as an argument, such as:
NSString *plistPath = [bundle pathForResource:filetName ofType:#"plist"];
Is there no way to assign an element of a string array to a string variable?
Update from 2014: The code in this post actually would work these days since special syntactic support has been added to the framework and compiler for indexing NSArrays like names[0]. But at the time this question was asked, it gave the error mentioned in this question.
You don't use C array notation to access NSArray objects. Use the -objectAtIndex: method for your first example:
NSString *fileName = [names objectAtIndex:0];
The reason for this is that NSArray is not "part of Objective-C". It's just a class provided by Cocoa much like any that you could write, and doesn't get special syntax privileges.
NSArray is a specialized array class unlike C arrays. To reference its contents you send it an objectAtIndex: message:
NSString *fileName = [names objectAtIndex:0];
If you want to perform an explicit cast, you need to cast to an NSString * pointer, not an NSString:
NSString *fileName = (NSString *)[names objectAtIndex:0];
With the new Objective-C literals is possible to use:
NSString *fileName = names[0];
So your code could look like this:
- (void)test5518658
{
NSArray *names = #[
#"FirstList",
#"SecondList",
#"ThirdList"];
NSString *fileName = names[0];
XCTAssertEqual(#"FirstList", fileName, #"Names doesn't match ");
}
Check Object Subscripting for more information.