I have 5 property with name address1, address2, ..... , address5. Now i want to iterate through all the property and assign them some value from array as follows.
for (int i=0; i<5; i++) {
self.address *value of i+1* = endAddress[i]; // like address1 = endAddress[0] and address2 = endAddress[1]
}
Ia there any way to achieve this? If yes, then how?
I googled it but unable to find a solution of adding integer with property instead found solutions to add integer with NSString.
Thanks in advance.
Key Value coding could be used for this, however the value being stored must be an Objective-C object, and not a primitive type. So for a number this means using NSNumber:
#property NSNumber *address1;
#property NSNumber *address2;
#property NSNumber *address3;
#property NSNumber *address4;
#property NSNumber *address5;
...
for (int i=0; i<5; i++) {
NSString *keyName = [NSString stringWithFormat:#"address%d", i + 1];
[self setValue:#(endAddress[i])
forKey:keyName];
}
Related
I have a model class object which has the following properties
#property (nonatomic, strong) NSString *place;
#property (nonatomic, strong) NSString *date;
I am setting these properties from a controller class object.
I want to perform a null check of my model class object properties. So I want to write a for loop like following.
for (property in modelObject)
{
if (object == [NSNull null])//object is a property of modelobject
{
//the next two lines wont be true but need to check that
if([property isKindOfClass:[NSString Class]]) property = #"no place";
if([property isKindOfClass:[NSDate Class]]) property = #"No date;
}
}
My question is,
If the model class object property is set to null how can I check if the property is null and also the declaration type of that property?
Directly checking the two properties instead of looping through the properties won't be helpful because in the actual scenario there are lot of properties with different types for the model class.
Thanks in advance.
Add a method in Model Class
- (void)nullCheck {
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList([self class], &outCount);
for (i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property)];
id propertyValue = [self valueForKey:(NSString *)propertyName]; //check propertyValue here
//set property value here
[self setValue:#"some value" forKey:(NSString *)propertyName];
const char * type = property_getAttributes(property);
NSString *attr = [NSString stringWithCString:type encoding:NSUTF8StringEncoding];
NSString * typeString = [NSString stringWithUTF8String:type];
NSArray * attributes = [typeString componentsSeparatedByString:#","];
NSString * typeAttribute = [attributes objectAtIndex:0];
NSString * propertyType = [typeAttribute substringFromIndex:1];
}
free(properties);
}
First, you cant do this to check the properties on the modelObject view controller, if I understand correctly that that is what you want to do :
for (property in modelObject)
What this would do is iterate through an array called modelObject. So if you had first added your properties to that array, that would be fine. There is no simple way to iterate through every property that any class has - you just wouldnt want to do that anyway. You first need to either add them to an array for reference, or refer to them in some other collection type.
Second, you can quickly check if a property remains nil - ie it has never been used, like this :
if (object) {
}
This will return true if the object is not 'nil'. You dont have to use [NSNull null] for what you are trying to achieve. So you could instead do this :
if (!place) {
place = #"no place";
}
if (!date) {
date = #"no date";
}
Say I have n variables
NSNumber* A = #(1);
NSNumber* B = #(2);
NSNumber* C = #(3);
NSNumber* D = #(4);
NSNumber* E = #(5);
...
I need a dictionary like
{#"A":#(1), #"B":#(2), #"C":#(3), #"D":#(4), ... }
One can imagine a more cumbersome example that would be tedious to type out
I think saw a C style function for it but I can't remember. Something like NSDictionaryForVariables()
The C preprocessor macro (not a function) you're looking for is NSDictionaryOfVariableBindings. However, outside of Auto Layout (and, debatably, even there), it's not really a great idea to be setting up dependencies between runtime and compile-time identifiers like that.
Depending on what you're trying to actually accomplish, Key-Value Coding might be a better solution.
It's not a good approach you may find another way to solve your issue but if you want to have an idea about your requested solution here here my try
Our properties
#interface TestyViewController ()
#property (nonatomic) NSNumber* a;
#property (nonatomic) NSNumber* b;
#property (nonatomic) NSNumber* c;
#property (nonatomic) NSNumber* d;
#end
Set the values
- (void)viewDidLoad {
[super viewDidLoad];
self.a=#(1);
self.b=#(2);
self.c=#(3);
self.d=#(4);
}
Get our instance variables
-(NSArray *)propertyNames{
unsigned int propertyCount = 0;
objc_property_t * properties = class_copyPropertyList([self class], &propertyCount);
NSMutableArray * propertyNames = [NSMutableArray array];
for (unsigned int i = 0; i < propertyCount; ++i) {
objc_property_t property = properties[i];
const char * name = property_getName(property);
[propertyNames addObject:[NSString stringWithUTF8String:name]];
}
free(properties);
return propertyNames;
}
Create the dictionary
- (IBAction)buttonClicked:(id)sender
{
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
for (NSString* varName in [self propertyNames])
{
[dict setObject:[self valueForKey:varName] forKey:varName];
}
NSLog(#"%#",dict);
}
result
2015-07-15 20:30:56.546 TestC[879:27973] {
a = 1;
b = 2;
c = 3;
d = 4;
}
#property NSMutableArray*textFieldsA;
#property NSMutableArray*textFieldsB;
#property NSMutableArray*textFieldsR;
#property NSMutableArray *operandArrayA;
#property NSMutableArray *operandArrayB;
_textFieldsA = #[self.textFieldA0, self.textFieldA1, self.textFieldA2, self.textFieldA3, self.textFieldA4, self.textFieldA5, self.textFieldA6, self.textFieldA7, self.textFieldA8];
_textFieldsB = #[self.textFieldB0, self.textFieldB1, self.textFieldB2, self.textFieldB3, self.textFieldB4, self.textFieldB5, self.textFieldB6, self.textFieldB7, self.textFieldB8];
_textFieldsR = #[self.textFieldR0, self.textFieldR1, self.textFieldR2, self.textFieldR3, self.textFieldR4, self.textFieldR5, self.textFieldR6, self.textFieldR7, self.textFieldR8];
for (int i = 0; i < 9; i++) {
_operandA = [((UITextField*)_textFieldsA[i]).text integerValue];
_operandB = [((UITextField*)_textFieldsB[i]).text integerValue];
[self.arithmetic setOperandA:_operandA operandB:_operandB operator:_operator];
_finalString = [NSString stringWithFormat:#"%d",[self.arithmetic result]];
((UITextField*)_textFieldsR[i]).text = _finalString;
}
how can i put the integerValue of
self.textFieldA0.text , self.textFieldA1.text , self.textFieldA3.text ........self.textFieldA8.text
in to the array (operandArrayA)?
i have tried
operandArrayA[i] = [((UITextField*)_textFieldsA[i]).text integerValue];
but it is not work, how should i do?
Unfortunately you can not add primitive datatypes in NSArray. You need to create object of NSNumber for integer value. Store this object to an array.
Like this:
NSNumber *number = #([((UITextField*)_textFieldsA[i]).text integerValue]);
operandArrayA[i] = number;
You need to alloc and initialize all the arrays..like below
operandArrayA=[[NSMutableArray alloc]init];
operandArrayB=[[NSMutableArray alloc]init];
//if u want to store strings
[operandArrayA addObject:((UITextField*)_textFieldsA[i]).text];
[operandArrayB addObject:((UITextField*)_textFieldsB[i]).text];
//(OR) if u want to store integer value then u need to convert to NSNumber
[operandArrayA addObject:[NSNumber numberWithInt:[((UITextField*)_textFieldsA[i]).text integerValue]]];
[operandArrayB addObject:[NSNumber numberWithInt:[((UITextField*)_textFieldsB[i]).text integerValue]]];
//(OR)
operandArrayA[i]=[NSNumber numberWithInt:[((UITextField*)_textFieldsA[i]).text integerValue]];
operandArrayB[i]=[NSNumber numberWithInt:[((UITextField*)_textFieldsB[i]).text integerValue]];
Hope it helps you..
I am trying to get the total value totalPurchaseSum of an property stockPurchasePrice from all objects in an array arrPurchaseActions.
This are the properties (user.h):
#property (nonatomic, strong) NSMutableArray *arrPurchaseActions;
#property (nonatomic) CGFloat totalSumPurchased;
-(CGFloat)totalSumPurchased:(CGFloat)stockPurchasePrice;
This is the method I am trying to use (User.m):
-(CGFloat)totalSumPurchased:(CGFloat)stockPurchasePrice
{
CGFloat totalSumPurchased = 0;
size_t count = [self.arrPurchaseActions count];
for (int i = 0; i < count; i++) {
totalSumPurchased = totalSumPurchased + [[self.arrPurchaseActions[i].stockPurchasePrice];
}
return totalSumPurchased;
}
Can anybody help me to get this working?
Try this:
NSNumber * sum = [self.arrPurchaseActions valueForKeyPath:#"#sum.stockPurchasePrice"];
This line:
totalSumPurchased = totalSumPurchased + [[self.arrPurchaseActions[i].stockPurchasePrice];
needs to be:
totalSumPurchased = totalSumPurchased + [[self.arrPurchaseActions[i] stockPurchasePrice];
You can't use the property accessor with objects of type id (which is what NSArray objectAtIndex: returns). Instead, call the getter method for the property.
I want to create a class that I want to serialize as XML using the property names and property values of the class. For that I created the following function in my base class (from which I will derive all my other classes):
- (NSString*) serialize
{
unsigned int outCount, i;
NSMutableString* s = [NSMutableString string];
Class currentClass = [self class];
while(currentClass != nil) {
objc_property_t *properties = class_copyPropertyList([self class], &outCount);
if(outCount > 0) {
for(i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
NSString *name = [NSString stringWithCString: property_getName(property) encoding: NSUTF8StringEncoding];
[s appendFormat: #"<%#>%#</%#>", name, (NSString*)property, name];
}
}
free(properties);
}
return (NSString*)s;
}
#end
I am assuming that all the properties are (nonatomic,strong) NSString* (for now - a more sophisticated code would come later). Now for some reason when I hit the line
[s appendFormat: #"<%#>%#</%#>", name, (NSString*)property], name];
I am getting a EXC_BAD_ACCESS exception.
What am I doing wrong?
Thanks in advance!
property is coming back as a c string, not an NSString. Just change your format to print out a c string instead of trying to convert it, something like this:
[s appendFormat: #"<%#>%s</%#>", name, property, name];
Found it. Just use
NSString *value = [self valueForKey:name];
to get the property value...
When you use %# with an object, the compiler basically tries to help you by calling that object's description method. Your objc_property_t variable doesn't support that method. I think it's actually a struct...You can't just cast that to NSString. You need to decide WHAT attribute you want to print from it, and then retrieve that value from it. Similar to what you did using property_getName for retrieving the "name" attribute.