testing object for key instead of keys value [closed] - ios

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.

Related

How dynamically initialise object in Swift 3 [closed]

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 use below line of code to allocate an Object(Suppose my Object name is Car) dynamically.
[self initliazieObject:[Car class]]
- (id)initliazieObject:(Class)model{
id record = [[model alloc] init];
return record;
}
How I can do this in swift 3.
Exactly as in Objective-C. Try this in a playground:
class Car : NSObject {}
func factory(type:NSObject.Type) -> NSObject {
return type.init()
}
let c = factory(type:Car.self)
print(type(of:c)) // Car
(We can get fancy and do clever things with generics or Self to specify the type of the returned object more precisely, but my goal in this code is simply to do things the dumb way, just like Objective-C.)

Set bool property of all objects in the array

I've a model class called PhotoItem. In which I have a BOOL property isSelected
#interface PhotoItem : NSObject
/*!
* Indicates whether the photo is selected or not
*/
#property (nonatomic, assign) BOOL isSelected;
#end
I've an NSMutableArray which holds the object of this particular model. What I want to do is, in a particular event I want to set the bool value of all objects in the array to true or false. I can do that by iterating over the array and set the value.
Instead of that I tried using:
[_photoItemArray makeObjectsPerformSelector:#selector(setIsSelected:) withObject:[NSNumber numberWithBool:true]];
But I know it won't work and it didn't. Also I can't pass true or false as the param in that (since those are not object type). So for fixing this issue, I implemented a custom public method like:
/*!
* Used for setting the photo selection status
* #param selection : Indicates the selection status
*/
- (void)setItemSelection:(NSNumber *)selection
{
_isSelected = [selection boolValue];
}
And calling it like:
[_photoItemArray makeObjectsPerformSelector:#selector(setItemSelection:) withObject:[NSNumber numberWithBool:true]];
It worked perfectly. But my question is, Is there any better way to achieve this without implementing a custom public method ?
Is there any better way to achieve this without implementing a custom public method?
This sounds like you are asking for opinion, so here is mine: Keep it simple.
for (PhotoItem *item in _photoItemArray)
item.isSelected = YES;
Why obfuscate a simple thing with detours through obscure methods when you can write code that anybody will immediately understand?
Another way of doing the same thing would be:
[_photoItemArray setValue:#YES forKey:#"isSelected"];
This does not need the custom additional setter method because KVC does the unboxing for you.
But again I would vote against using such constructs. I think they are distracting from the simple meaning and confusing developers that come after you.

Incompatible integer to pointer conversion sending nsinteger [closed]

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

Getting an already instantiated instance variable from another class in Objective C [duplicate]

This question already has answers here:
Passing data between view controllers
(45 answers)
Closed 8 years ago.
I'm hitting a bit of a brick wall in getting a program to work in Objective C. In fact, I've been struggling with this problem all day.
I have a ViewController which takes input from a view, which will contain a float variable (weight). I'll need to use this variable in other parts of my program, and therefore I've assigned the data to a very basic class, as follows:
//patient.h
#import <Foundation/Foundation.h>
#interface Patient : NSObject
#property float weight;
#end
and the .m:
//patient.m
#import "Patient.h"
#implementation Patient
float weight;
#end
My first view controller: -There's nothing of note in the .h file aside from connections to UI elements, and:
#import "Patient.h"
In the interests of clarity, I've omitted the code for simply servicing the UIview and getting the user inputs
//demographicsViewController.m
#import "demographicsViewController.h"
#interface demographicsViewController ()
{
// declares an array, for the custom picker
NSArray *_agePickerArray;
NSArray *_ageWeightArray;
}
#end
#implementation demographicsViewController
/* (omitting a sizeable chunk of code in the interests of clarity. Please let me know if you think it important to see) */
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
//captures the output on the text field and converts it into a float that can be slotted straight in to the model. Sets a default value if the field is blank
float weightTextFieldInterrogation;
if([[_weightDisplayTextBox text] length] != 0)
{
weightTextFieldInterrogation = [_weightDisplayTextBox.text floatValue];
}
else
{
weightTextFieldInterrogation = 70.0;
}
//Takes the weight value and plumbs it into the central weight database ready to be used in other parts of the app
NSLog(#"weight: %.1f",weightTextFieldInterrogation);
[Patient.weight] = weightTextFieldInterrogation;
Patient* thePatient = [[Patient alloc]init];
[thePatient setWeight:weightTextFieldInterrogation];
NSLog(#"Stored weight: %.1f",thePatient.weight);
}
#end
The problem I'm having is that when I try to look up the value I've stored for weight or thePatient.weight, the variable is either unrecognised (despite #import "patient" and #import "demographicsViewController), and if I instantiate it again, then the value is blank.
I've read up on a number of different solutions to this, but have been so far unsuccessful at getting any to work. I'd be really grateful if there are any bright ideas about fixing this.
Your problem is that the object you create is destroyed almost immediately after you create it. You are expecting that the instance will float around so that you can pick it up again in the future but it won't.
There are some ways to cheat, but really you should be taking that instance and passing it to some other view controller which wants / needs it, or storing that float value somewhere else (like in a file on disk, or in user defaults).
This is really an OOP question about what you use objects for and how long they exist for.

Conversion from NSString to int not working [closed]

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];

Resources