Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm pushing to another WKInterfaceController when a row is selected but I can't seem to pass the rowIndex as context for my new controller which I would like to do.
// Push to next controller and pass rowIndex as context
- (void)table:(WKInterfaceTable *)table didSelectRowAtIndex:(NSInteger)rowIndex {
[self pushControllerWithName:(NSString *)#"ZoomPokeController"
context:rowIndex];
}
This code gives the error
incompatible integer to pointer conversion sending NSInteger: implicit conversion of 'NSInteger' (aka 'int') to 'id' is disallowed with ARC.
I can change my context to nil and the build succeeds but of course then I have no context. I've taken a look at the class documentation which has helped me a lot so far and similar questions on stackoverflow but I'm stuck not knowing how to write this. Thanks for any help.
The error
"implicit conversion of 'NSInteger' (aka 'int') to 'id' is disallowed with ARC."
Clearly says that you are passing NSInteger as a parameter where as method it suppose to be id.
In below line second parameter required id object.
[self pushControllerWithName:(NSString *)#"ZoomPokeController" context: rowIndex];
With the help of #fabian789, It is clear now that in WKInterfaceController Class Reference
that method required id object as second parameter.
To pass an integer there, you can convert your NSInteger to an NSNumber and pass in a second parameter.
- (void)table:(WKInterfaceTable *)table didSelectRowAtIndex:(NSInteger)rowIndex {
NSNumber *rowValue = [NSNumber numberWithInteger:rowIndex];
[self pushControllerWithName:#"ZoomPokeController" context: rowValue];
}
You can then in the target controller get the row index by calling integerValue on the context.
You are sending wrong parameter type. Cast the rowIndex to int Try this:
- (void)table:(WKInterfaceTable *)table didSelectRowAtIndex: (NSInteger) rowIndex {
NSNumber *val = [NSNumber numberWithInteger: rowIndex]
[self pushControllerWithName:#"ZoomPokeController" context: val];
}
Hope this help... :)
The Error clearly States what you are doing wrong, You are Sending an NSInteger type to only an integer, try declaring the context parameter as an NSInteger or use it like this,
[self pushControllerWithName:(NSString *)#"ZoomPokeController" context: (int)rowIndex];
but the earlier method is more effective
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I'm using valueForKey: to check isKindOfClass:. But some of these do not have a value and thus don't return anything. How do I test the actual key rather than the value of the key? If object.animal is an NSString with #"Cat" then obviously [[object valueForKey #"animal"] isKindOfClass:[NSString class]] checks out as a string. But if object.animal hasn't been given a value, I still want to know what kind of property animal was meant to be.
You can obtain this information using Objective-C runtime for properties. If you have
#property (readonly) NSString *animal;
You can use following code:
#import <objc/runtime.h>
// ...
objc_property_t property = class_getProperty(object.class, "animal");
const char* attr = (property != NULL) ? property_getAttributes(property) : NULL;
attr is C string, like following: "T#\"NSString\",R". You can extract class name from this string. See Apple documentation regarding property_getAttributes result. Note that this solution will only work, if animal is declared as property.
Much easier way to handle this situation:
#interface MyObject : NSObject
#property (readonly) NSString *animal;
+ (Class)animalClass;
#end
#implementation MyObject
+ (Class)animalClass {
return [NSString class];
}
#end
Answer to your question is here property type or class using reflection
Although I must point out using this is highly unadvisable. You might want to re think your approach if your really need to resort to this.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
It's not an actual problem but it is frustrating me..
I was looking for a better way to right an IF statement with multiple values that can be accepted.
For example:
if ([[myJson objectForKey:#"pages"] intValue] == 0 || [[myJson objectForKey:#"pages"] intValue] == 3)
Isn't there any way to write something like:
if ([[myJson objectForKey:#"pages"] intValue] == 0 | 3)
{
}
Thanks !!
No, not really. You could do this:
int pages = [[myJson objectForKey:#"pages"] intValue];
if (pages == 0 || pages == 3)
That's what I would recommend. The code you posted is both less efficient and harder to maintain than the code I show.
In your code you actually invoke the objectForKey and intValue methods twice on the same object.
Plus if at some point in the future you change the key value, or the variable name, you have to make the same edit in 2 places, which is more work and adds another chance to introduce a new copy/paste error.
In addition to the other valid answers, you could use a switch:
int numberOfPages = [[myJson objectForKey:#"pages"] intValue];
switch (numberOfPages) {
case 0:
case 3: {
NSLog(#"Is 0 or 3");
break;
}
default: {
NSLog(#"Is NOT 0 or 3");
break;
}
}
This is a much better method as it is clean and easier to read:
int x = [[myJson objectForKey:#"pages"] intValue];
if (x == 0 || x == 3) {
}
You are highly optimistic there.
If myJson is not an NSDictionary your app will crash.
If myJson[#"pages"] is not an NSNumber then your app will crash.
If myJson[#"pages"] does not exist then intValue will return 0.
If myJson[#"pages"] has a value of 0.9 or 3.7 then intValue will return 0 or 3.
I suggest you add a category to NSDictionary with a method like integerValueForKey: withDefault where you lookup an item, check that it is an NSNumber with an integer value, return that value or return the default value.
As David Rönnqvist pointed out, it is mostly a matter of preference. I would personally go with NSArray containing allowed values. This way you won't clutter your code with unnecessary intValue calls. Also adding another allowed value will only require adding a single value to an array instead of adding another condition inside if statement.
Note that you can use Objective-C literal syntax to make the code more concise.
NSArray *allowedValues = #[#0, #3];
if([allowedValues containsObject:myJson[#"pages"]]) {
}
If [myJson objectForKey:#"pages"] is an NSNumber. You could do this:
if([#[#0, #3] containsObject:[myJson objectForKey:#"pages"]])
And if myJson is an NSDictionary you could even shorten it to:
if([#[#0, #3] containsObject:myJson[#"pages"]])
It's not necessarily optimal, but it does provide you with a lot more flexibility when adding more values to check against, which it sounds like you're looking for as opposed to the fastest code. If you're just checking a few values I'm assuming speed of execution is not an issue.
Side note: this works because NSArray's containsObject: method calls isEqual: on every object. NSNumber's isEqualToNumber: gets called. This will also work with NSString instead of NSNumber if that's what you're working with. Just change the search array to hold NSString objects in that case.
I am new to objective C and trying to learn it. I am trying to write calculator program which performs simple mathematical calculation(addition, subtraction and so forth).
I want to create an array which stores for numbers(double value) and operands. Now, my pushOperand method takes ID as below:
-(void) pushOperand:(id)operand
{
[self.inputStack addObject:operand];
}
when I try to push double value as below:
- (IBAction)enterPressed:(UIButton *)sender
{
[self.brain pushOperand:[self.displayResult.text doubleValue]];
}
It gives my following error: "Sending 'double' to parameter of incompatible type 'id'"
I would appreciate if you guys can answer my following questions:
'id' is a generic type so I would assume it will work with any type without giving error above. Can you please help me understand the real reason behind the error?
How can I resolve this error?
id is a pointer to any class. Hence, it does not work with primitive types such as double or int which are neither pointers, nor objects. To store a primitive type in an NSArray, one must first wrap the primitive in an NSNumber object. This can be done in using alloc/init or with the new style object creation, as shown in the two snippets below.
old style
NSNumber *number = [[NSNumber alloc] initWithDouble:[self.displayResult.text doubleValue]];
[self.brain pushOperand:number];
new style
NSNumber *number = #( [self.displayResult.text doubleValue] );
[self.brain pushOperand:number];
I suggest using it with an NSNumber: Try not to abuse using id where you don't need to; lots of issues can arise if not.
- (void)pushOperand:(NSNumber *)operand
{
[self.inputStack addObject:operand];
}
- (IBAction)enterPressed:(UIButton *)sender
{
[self.brain pushOperand:#([self.displayResult.text doubleValue])];
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
i have created an a nsstring idd variable in .h. and synthesized in .m. Now i have an int variable b and want to store the value of idd in b. Now when i convert idd to int. it not working the b always give me the 0 value.
.h
#property(retain, nonatomic) IBOutlet NSString *idd;
.m
int b=[idd intValue];
NSLog(#"the value of b=%d",b);
IBOutlets and IBActions are macros that mark variables and methods that can be referred to by Interface Builder to link UI elements to your code. They're typically linked to subclasses of NSResponder (like NSButton, NSView, etc.); not NSString's. Unless idd is bound to something in a NIB it won't have any value other than the default (zero). If idd is bound to a GUI object (control) then what you probably want is that controls value (in which case your code is correct).
idd probably doesn't have a value, or has a value that can't be parsed into an integer. Try NSLoging idd to see what it contains.
do
idd = #"2";
int b = [idd intValue];
NSLog(#"b = %i", b);
and that should display 2 as b
You need
int b=[self.idd intValue];
My brain is failing me today. I know this has got to be a simple one, but I just don't see it.
CGFloat *minutes = [self.displayData objectForKey:index];
Incompatible integer to pointer conversion sending 'NSUInteger' (aka 'unsigned int') to parameter of type 'id'
index is a NSUInteger in a loop, (0 1 2 3 etc)
How do I get past this one? Thanks.
The dictionary waits for an object as the key (id) rather than a plain integer (NSUInteger).
Try wrapping the integer in a NSNumber object.
CGFloat *minutes = [self.displayData objectForKey:[NSNumber numberWithUnsignedInteger:index]];
The -objectForKey: method returns a value of type id, but you're trying to assign that to a CGFloat*, which isn't compatible with id because CGFloat isn't a class. If you know that the object you're retrieving from the dictionary is a certain type, say an NSNumber, you can take steps to convert it to a CGFloat when you get it.
Also, you're trying to use an int as a key into a dictionary, but dictionaries require their keys to be objects too. If you want to access your objects by index, store them in an array instead of a dictionary.
Putting it all together, you'd have something like this:
// after changing the displayData to an array
NSNumber *number = [self.displayData objectAtIndex:index];
CGFloat minutes = [number floatValue];
You should not be using a pointer like this:
CGFloat minutes = [self.displayData objectForKey:index];
Easy question. Just don't use NSUIntegrer. Instead of it, do the following:
id index;//then set the index