I'm using function random()%some integer in a method of one of my app's classes and I have no idea where to put srandom (time (NULL)) to generate not pseudorandom but true random numbers. I have already put it in viewDidLoad and viewWillAppear but it doesn't help.
- (NSMutableDictionary *)getUsersFromServer
{
srand(time(NULL));
//here we're getting list of users from the server
NSMutableDictionary * users = [[[NSMutableDictionary alloc] init] autorelease];
for (int i = 0;i < 19;i++)
{
int wins = rand()%100; float f_wins = (float)wins;
int losses = rand()%100; float f_losses = (float)losses;
int withdr = rand()%100; float f_withdr = (float)withdr;
float win_per = f_wins / ((f_wins + f_losses + f_withdr) / 100.0);
[userresults setArray:[NSMutableArray arrayWithObjects:[NSNumber numberWithInt:wins],
[NSNumber numberWithInt:losses],
[NSNumber numberWithInt:withdr],
[ NSNumber numberWithFloat:win_per],
nil]];
[users setObject:userresults forKey:[NSString stringWithFormat:#"Pfeffer ID %i",i]];
}
[userresults release];
return users;
}
something like this... the code looks awful but its sense is understandable. rand() produces same numbers for each loop iteration. If I use arc4random() it changes nothing. still same numbers
I don't think this is a issue about randomness or seeds at all, I don't use Objective-C, but ...
// for each loop iteration:
[userresults setArray: .... ] // <-- modify object known as userresults?
[users setObject:userresults ....] // <-- isn't that the SAME userresults object?
That is, I believe you have the same object multiple times in users: shouldn't a new result object be created each iteration?
Also, see srand() — why call it only once? -- for why using srand at the top of this method might not be ideal. Alternatively, this post recommends arc4random as it does not require a manual seeding and is a "stronger" pseudo-random generator.
Happy coding.
Related
Here is the code:
TrailLayer * layer = (TrailLayer*)[_layers objectAtIndex:(int)^{
if (_segmentNumber < [_segmentArray count]) {
return _segmentNumber;
} else {
return _segmentNumber - 1;
}
}];
what is the problem here? Here, all the _Variables are IVARs. I am first time using Blocks, can someone help me identifying this problem. Its giving EXC_BAD_INSTRUCTION here.
Thanks.
Try this code, First write block to get the index number, and use that number to retrieve value from array
int (^segmentIndex)(int) = ^(int segmentNumber){
if (segmentNumber < [_layers count]) {
return segmentNumber;
} else {
return segmentNumber - 1;
}
};
NSLog(#"Trail Layer %#", [_layers objectAtIndex:segmentIndex(_segmentNumber)]);
TrailLayer * layer = (TrailLayer*)[_layers objectAtIndex:segmentIndex(_segmentNumber)];
A block is a runnable thing like a function, basically a piece of code that you can store, pass around, and run later (or not). You want to pass an integer to objectAtIndex:, so passing a block makes absolutely no sense whatsoever.
What you could have meant to do was run the block, and then pass its result to objectAtIndex:. In that case, you would have to run the block:
TrailLayer * layer = [_layers objectAtIndex:^{
if (_segmentNumber < [_segmentArray count]) {
return _segmentNumber;
} else {
return _segmentNumber - 1;
}
}()]; // <-- run the block
However, defining a block (which is a full-fledged object, and does a lot of fancy stuff) just to run it immediately is kinda silly. If you want to just be able to use a piece of code as an expression, you could use the "statement expressions" language extension supported by both GCC and LLVM:
TrailLayer * layer = [_layers objectAtIndex:({
int result;
if (_segmentNumber < [_segmentArray count]) {
result = _segmentNumber;
} else {
result = _segmentNumber - 1;
}
result;
})];
But really you should just do a regular C conditional expression in this case:
TrailLayer * layer = [_layers objectAtIndex:
_segmentNumber < [_segmentArray count] ?
_segmentNumber : _segmentNumber - 1];
I'm trying to create a function to calculate the mean, max, min and standard deviation of a set of numbers.
I'd like it to work like the UIColor function - (void)getRed:green:blue:alpha. i.e. you pass in the four float values and the function then overwrites them.
I'm struggling to find the right syntax for it.
My function is...
- (void)calculateStatsAverage:(float)average
standardDeviation:(float)standardDeviation
minimum:(float)minimum
maximum:(float)maximum
{
//pseudo code
average = total / count;
minimum = min value;
etc...
//
}
The problem I'm getting is getting the values out again.
If I change the function to use float* (which is what the UIColor function does) then my calculations don't like assigning the variables.
To simplify...
Imagine these functions. The first is called from elsewhere.
- (void)runThisFunction
{
float someOutputValue = 0.0;
[self changeTheValue:someOutputValue];
NSLog(#"The value is %f", someOutputValue);
}
- (void)changeTheValue:(float)value
{
value = 10.0;
}
I'd like this code to output "The value is 10.0"; But at the moment I'm getting "The value is 0.0".
Please could you show me how to write these two functions. From there I'll be able to work out the rest.
Thanks
- (void)passByRefMethod:(float *)ptr
{
*ptr = MYVALUE;
}
Sorry for formatting, typed on phone. Hope this helps!
This technique is often called pass by reference, and it's part of C so you can use that to search for more info.
Your NSLog is displaying the value of the local variable 'someOutputValue', which has been assigned to be 0.0.
Your 'changeTheValue' method has no effect.
The following code may help,
- (void)runThisFunction
{
float someOutputValue = 0.0;
float resultOfCalc = [self calcTheValue:someOutputValue];
NSLog(#"The value is %f", resultOfCalc);
}
- (float) changeTheValue:(float)value // note that this method returns a float
{
float newValue;
// do whatever calc is appropriate, e.g.
newValue = value + 10.0;
return newValue; // pass back the result of calc
}
This will output,
The value is 10.
I'm having a strange problem with the following code:
int c = [whatsNewArray1 count];
int t = [dames count];
int i = 0;
int o= 0;
NSMutableArray *finalWhatsNew = [[NSMutableArray alloc]init];
while (i<c){
NSLog(#"teller array %i", i);
while(t>o){
NSLog(#"dames %i", i);
if ([[[dames objectAtIndex:o] productId] isEqualToString:[whatsNewArray1 objectAtIndex:i]]){
[finalWhatsNew addObject:[dames objectAtIndex:o]];
NSLog(#"inner dames%i", i);
}
o++;
}
i++;
}
This code retrieves al the entries from the "dames" array which are stated in the "finalWhatsNew" array. Problem with this is that the if is only get called the first time.
To make it a little bit clearer, the whole code is working fine, but as soon "i" is ++ to 1. the if statement isn't called. It looks like ios i canceling it out after the first time for performance reason or somethins like that. Anybody has any ideas?
Thnx!!!
After inner loop is finished for the first time the o counter is equal to array's count and so it won't enter the loop again. To make it work you must reset o counter on each iteration of the outer loop:
while (i<c){
o = 0;
while (t > o)
...
Edit: For clearer code (and probably better performance) you can use fast enumeration instead of usual for/while loops:
for (NSString *searchId in whatsNewArray1){
for (YourObject *obj in dames){
if ([[obj productId] isEqualToString:searchId])
[finalWhatsNew addObject: obj];
}
}
Edit2: Also you can eliminate 2nd loop by using NSPredicate to filter your array:
for (NSString *searchId in whatsNewArray1){
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"productId == %#",searchId];
[finalWhatsNew addObjectsFromArray:[dames filteredArrayUsingPredicate:predicate]];
}
As Vladimir says, you need to reset o after each iteration of the outer loop. Ideally you switch to for-statements here, as they fit what you're doing exactly:
for (int i=0; i<c; ++i) {
// ...
for (int o=0; o<t; ++o) {
// ...
I would like to obtain a list of all the properties of an ABPersonRef and ABGroupRef without having to use the iOS predefined keys of kABPersonFirstNameProperty, kABPersonLastNameProperty... I'm playing with the address book and I'd like to iterate over all values for a particular person. I know there are predefined keys but Apple could very well add new ones in the future so I'd like to do something like:
ABAddressBookRef addressBook = ABAddressBookCreate();
NSArray *allPeople = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
for (int i = 0; i < [allPeople count]; ++i) {
ABRecordRef person = [allPeople objectAtIndex:i];
// This is the line that I can't figure out.
NSArray *allProperties = (NSArray *)ABRecordCopyArrayOfAllProperties(person);
}
I know that I'll encounter multivalue items that I'll have to loop though later, but the goal is to obtain a list of keys that I can iterate over for the single value properties. I don't care what the returned class is, NSArray, NSDictionary... whatever.
I greatly appreciate any advice!
You can try the following:
With ARC:
NSDictionary* dictionaryRepresentationForABPerson(ABRecordRef person)
{
NSMutableDictionary* dictionary = [NSMutableDictionary dictionary];
for ( int32_t propertyIndex = kABPersonFirstNameProperty; propertyIndex <= kABPersonSocialProfileProperty; propertyIndex ++ )
{
NSString* propertyName = CFBridgingRelease(ABPersonCopyLocalizedPropertyName(propertyIndex));
id value = CFBridgingRelease(ABRecordCopyValue(person, propertyIndex));
if ( value )
[dictionary setObject:value forKey:propertyName];
}
return dictionary;
}
We using the localized name of the property - in different locales will have different keys.
The number of properties may change in the next version of iOS.
Maybe it makes sense to go through to the number of properties as long as the propertyName does not become UNKNOWN_PROPERTY
Aliaksandr's solution is not safe: for example if you attempt to create ABPerson records in a specific ABSource, and use this approach, you might find that contacts do not sync to that source properly.
I simply copied the list of 25 ABPropertyIDs from ABPerson, stuck them in a simple int[], and iterated over them...
// Loop over all properties of this Person
// taken from Apple's ABPerson reference page on 9.12.13.
// URL: https://developer.apple.com/library/ios/documentation/AddressBook/Reference/ABPersonRef_iPhoneOS/Reference/reference.html#//apple_ref/c/func/ABPersonGetTypeOfProperty
// count = 25. All are type ABPropertyID
int propertyArray[25] = {
kABPersonFirstNameProperty,
kABPersonLastNameProperty,
kABPersonMiddleNameProperty,
kABPersonPrefixProperty,
kABPersonSuffixProperty,
kABPersonNicknameProperty,
kABPersonFirstNamePhoneticProperty,
kABPersonLastNamePhoneticProperty,
kABPersonMiddleNamePhoneticProperty,
kABPersonOrganizationProperty,
kABPersonJobTitleProperty,
kABPersonDepartmentProperty,
kABPersonEmailProperty,
kABPersonBirthdayProperty,
kABPersonNoteProperty,
kABPersonCreationDateProperty,
kABPersonModificationDateProperty,
kABPersonAddressProperty,
kABPersonDateProperty,
kABPersonKindProperty,
kABPersonPhoneProperty,
kABPersonInstantMessageProperty,
kABPersonSocialProfileProperty,
kABPersonURLProperty,
kABPersonRelatedNamesProperty
};
int propertyArraySize = 25;
for ( int propertyIndex = 0; propertyIndex < propertyArraySize; propertyIndex++ ) {
...code here
}
I was expecting to find that in the NSAttributeDescription class, but only the default value is there.
Behind the scene I tought a validationPredicate was created but trying to reach it using
NSDictionary* dico= [[myManagedObject entity] propertiesByName];
NSAttributeDescription* attributeDescription=[dico objectForKey:attributeKey];
for (NSString* string in [attributeDescription validationWarnings])
just get me nowhere, no validationWarnings, no validationPredicates...
any thoughts on this ?
Edit1: It seems that getting the entity straight from the managedObject doesn't give you the full picture. Getting the Entity from the NSManagedObjectModel permits to reach the validationWarnings & validationPredicates...
Edit2:
Using the following code just after the creation of the model will list all the validationPredicates of the model. For some reasons, using it later (at the time I try too validate for example) will not display anything !
for (NSEntityDescription *entity in managedObjectModel) {
for (NSAttributeDescription* attributeDescription in [entity propertiesByName])
for (NSPredicate* predicate in [attributeDescription validationPredicates])
{
NSLog(#"---%#",[predicate predicateFormat]);
}
}
I think you problem is most likely caused by calling [entity propertiesByName] which returns dictionary of mixed NSAttributeDescription and NSRelationshipDescription. When I tried to run your code I got the odd result that the attribute objects where returned as NSCFStrings.
The following code works and note that it produces output even after the managed object model is frozen by use.
- (void) dumpAttributePredicates{
NSLog(#"start dumpAttributePredicates");
for (NSEntityDescription *entity in managedObjectModel) {
NSDictionary *attribs=[entity attributesByName];
for (NSAttributeDescription *eachA in [attribs allValues]) {
NSArray *vps=[eachA validationPredicates];
for (NSPredicate *p in vps) {
NSLog(#"p =%#",[p predicateFormat]);
}
}
}
NSLog(#"end dumpAttributePredicates");
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification{
[self dumpAttributePredicates];
NSManagedObject *mo=[NSEntityDescription insertNewObjectForEntityForName:#"TestEntity" inManagedObjectContext:self.managedObjectContext];
NSLog(#"mo=%#",mo);
[self dumpAttributePredicates];
}
Which produces this output:
start dumpAttributePredicates
p =SELF >= 0
p =SELF <= 100
p =length >= 0
p =length <= 100
end dumpAttributePredicates
mo=<NSManagedObject: 0x10016f490> (entity: TestEntity; id: 0x10016f540 <x-coredata:///TestEntity/tA91445DF-4669-4018-A761-7383E3A73EF42> ;
data: {
attributeOne = 0;
attributeTwo = nil;
})
start dumpAttributePredicates
p =SELF >= 0
p =SELF <= 100
p =length >= 0
p =length <= 100
end dumpAttributePredicates
Make sure you don't confuse entities with NSManagedObject or its subclasses. Entities are the analogs of classes, not instances and an entity only exist within a managed object model which in turn maybe an attribute of a managed object context.