Not sure exactly how to word this but basically I am doing this:
unsigned int propCount = 0;
objc_property_t *properties = class_copyPropertyList([self class], &propCount);
for(int idx = 0; idx < propCount; idx++) {
objc_property_t prop = *(properties + idx);
NSString *key = #(property_getName(prop));
NSString *key2 = #(property_getAttributes(prop));
NSLog(#"%#::%#", key,key2);
}
and it prints out
describeOther::T#"UITextField",&,N,V_describeOther
how can I assign "UITextField" to something or is it already assigned and I can access it like key2[1] or something??
EDIT:
I guess I could do a if statement with a contains constraint but not sure if thats the "cleanest" way to do it.
Get the range of the two double-quotes and extract the substring between those two ranges.
NSRange openQuote = [key2 rangeOfString:#"\""];
NSRange closeQuote = [key2 rangeOfString#"\"" options:NSBackwardsSearch];
NSUInteger start = openQuote.location + openQuote.length;
NSUInteger end = closeQuote.location;
NSRange nameRange = NSRangeMake(start, end - start);
NSString *name = [keys substringWithRange:nameRange);
Related
In my Objective-C code I'd like to take a NSString value, iterate through the letters, sum ASCII values of the letters and return that to the user (preferably as the NSString too).
I have already written a loop, but I don't know how to get the ASCII value of an individual character. What am I missing?
- (NSString*) getAsciiSum: (NSString*) input {
NSInteger sum = 0;
for (NSInteger index=0; index<input.length; index++) {
sum = sum + (NSInteger)[input characterAtIndex:index];
}
return [NSString stringWithFormat: #"%#", sum];
}
Note: I've seen similar questions related to obtaining ASCII values, but all of them ended up displaying the value as a string. I still don't know how to get ASCII value as NSInteger.
Here is the answer:
- (NSString *) getAsciiSum: (NSString *) input
{
NSString *input = #"hi";
int sum = 0;
for (NSInteger index = 0; index < input.length; index++)
{
char c = [input characterAtIndex:index];
sum = sum + c;
}
return [NSString stringWithFormat: #"%d", sum]);
}
This is working for me.
Hope this helps!
This should work.
- (NSInteger)getAsciiSum:(NSString *)stringToSum {
int asciiSum = 0;
for (int i = 0; i < stringToSum.length; i++) {
NSString *character = [stringToSum substringWithRange:NSMakeRange(i, 1)];
int asciiValue = [character characterAtIndex:0];
asciiSum = asciiSum + asciiValue;
}
return asciiSum;
}
Thank you to How to convert a NSString to NSInteger with the sum of ASCII values? for the reference.
i have a uitableview, which gets populated by a pulling data from a website, so there is a new string for every cell. To that, i want to have show a HEX for the user, based on the text in the cell.
I have tryed myself to make it, without luck, but luckly found a javascript script which does what i try to do. This script, i now need to convert to obj-c, i have tryed it myself, but failed. I hope to get some help.
javascript: http://jsfiddle.net/sUK45/
My try in obj-c (here the strings aint based on the data from the web, but just an array):
unichar hash = 0;
NSArray *strings = [NSArray arrayWithObjects:#"MA", #"Ty", #"Ad", #"ER", nil];
for (int i = 0; i < [[strings objectAtIndex:indexPath.row] length]; i++) {
hash = [[strings objectAtIndex:indexPath.row] characterAtIndex:i] + ((hash < 5) - hash);
}
NSString *colour = #"#";
for (int i = 0; i < 3; i++) {
int value = (hash >> (i * 8)) & 0xFF;
colour = [NSString stringWithFormat:#"%#%d", colour, value];
}
NSLog(#"%#", colour);
But the data i get, aint a useable HEX - NSlog:
#2432550
#3600
#3400
#1200
Probably this is not the only one mistake. Change
hash = [[strings objectAtIndex:indexPath.row] characterAtIndex:i] + ((hash < 5) - hash);
to
hash = [[strings objectAtIndex:indexPath.row] characterAtIndex:i] + ((hash << 5) - hash);
UPDATE:
Also change
colour = [NSString stringWithFormat:#"%#%d", colour, value];
to
colour = [NSString stringWithFormat:#"%#%02x", colour, (unsigned int)value];
UPDATE2:
I have fixed one more error and simplified code:
unsigned int hash = 0;
NSArray *strings = [NSArray arrayWithObjects:#"MA", #"Ty", #"Ad", #"ER", nil];
NSString *string = [strings objectAtIndex:indexPath.row];
for (int i = 0; i < string.length; i++) {
hash = [string characterAtIndex:i] + ((hash << 5) - hash);
}
NSString *color = [NSString stringWithFormat:#"#%06x", hash % 0x1000000];
NSLog(#"%#", color);
So I am inserting a class object into an NSMutable array, and then I am trying to manage the specific properties of each indexed object.
Here I create the NsMutableArray:
self.currentPuzzle = [[NSMutableArray alloc]init];
for(int i = 0; i < [temp length]; i++){ //temp is a string containing #'s and dots.
AnswerSpecifier *objectToGetIntoArray = [[AnswerSpecifier alloc]init];
objectToGetIntoArray.value = [[temp substringWithRange:NSMakeRange(i, 1)] intValue];
[self.currentPuzzle addObject:objectToGetIntoArray];
}
and here I am trying to change the value property of each object. value is an int property.
for (int i = 0; i < [self.board.boardString length]; i++) {
[self.currentPuzzle objectAtIndex:i].value = [[self.board.boardString substringWithRange:NSMakeRange(i, 1)] intValue];
}
However I get an error saying that the property value was not found on object of type id. Should I just create a new array and assign it to the old one? Is there a better way to do this?
Split your code up. This makes it easier to read and debug.
for (int i = 0; i < [self.board.boardString length]; i++) {
AnswerSpecifier *answer = self.currentPuzzle[i];
NSString *boardString = [self.board.boardString substringWithRange:NSMakeRange(i, 1)];
int value = [boardString intValue];
answer.value = value;
}
You don't get points for cramming as much code as possible into one line.
But if you really just want to fix the one line you need to put the cast in the proper place:
[(AnswerSpecifier *)self.currentPuzzle[i] setValue:[[self.board.boardString substringWithRange:NSMakeRange(i, 1)] intValue]];
Try type casting the object
((AnswerSpecifier *)[self.currentPuzzle objectAtIndex:i]).value = [[self.board.boardString substringWithRange:NSMakeRange(i, 1)] intValue];
Try to replace with:
for (int i = 0; i < [self.board.boardString length]; i++) {
[[self.currentPuzzle objectAtIndex:i] setValue:[[self.board.boardString substringWithRange:NSMakeRange(i, 1)] intValue]];
}
I am having trouble with some code. I narrowed it down to this problem: first of all, reverseString and 2 are both NSMutableStrings _input1 and _input2 are NSStrings, i'm trying to add zeros to the smallest string but it's not working correctly, this is what I got. reverseString is #"123" and reverseString2 is #"34567".
//they get initialized back into the original strings
_input1=reversedString;
_input2=reversedString2;
//appends 0 to the shortest value
while ([_input1 length]>[_input2 length]){
_input2=[_input2 stringByAppendingString:#"0"];
_length=[_input1 length];
}
while ([_input1 length]<[_input2 length]){
_input1=[_input1 stringByAppendingString:#"0"];
_length=[_input2 length];
}
//converts the string to an NSArray
for (int i=0; i <([_input1 length]); i++) {
NSString *TempStr = [_input1 substringWithRange:NSMakeRange(i, 1)];
[one addObject:[TempStr stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}
for (int i=0; i <([_input2 length]); i++) {
NSString *TempStr2 = [_input2 substringWithRange:NSMakeRange(i, 1)];
[two addObject:[TempStr2 stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}
Now I noticed that when it goes through this loop, the smallest one, _input1, gets set to #"" instead of adding zeros to the end. This is within a class, by the way.
This is also an error I receive:
objc[2291]: Method cache corrupted. This may be a message to an invalid object, or a memory error somewhere else.
objc[2291]: receiver 0x100300830, SEL 0x7fff8a689779, isa 0x7fff727b8bd0, cache 0x7fff727b8be0, buckets 0x7fff89b9b09c, mask 0x1, occupied 0x0, wrap bucket 0x7fff89b9b09c
objc[2291]: receiver 0 bytes, buckets 0 bytes
objc[2291]: selector 'length'
(lldb)
Just try with following code
if([_input1 length] > [_input2 length])
{
for (int i = 0 ; i < [_input1 length] - [_input2 length] ; i ++)
_input2 = [_input2 stringByAppendingString:#"0"];
}
else
{
for (int i = 0 ; i < [_input2 length] - [_input1 length] ; i ++)
_input1 = [_input1 stringByAppendingString:#"0"];
}
Try like this:-
NSString *input1=#"123";
NSString * input2=#"34567";
NSMutableArray *one=[NSMutableArray array];
NSMutableArray *two=[NSMutableArray array];
//appends 0 to the shortest value
while ([input1 length]>[input2 length]){
input2=[input2 stringByAppendingString:#"0"];
//length=[input1 length];
}
while ([input1 length]<[input2 length]){
input1=[input1 stringByAppendingString:#"0"];
// length=[input2 length];
}
for (int i=0; i <([input1 length]); i++) {
NSString *TempStr = [input1 substringWithRange:NSMakeRange(i, 1)];
[one addObject:[TempStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}
NSLog(#"%ld",[one count]);
for (int i=0; i <([input2 length]); i++) {
NSString *TempStr2 = [input2 substringWithRange:NSMakeRange(i, 1)];
[two addObject:[TempStr2 stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}
NSLog(#"%ld",[two count]);
Well your requirements are not very clear, but here's a cleaner version of the code you proposed
NSString *string1 = #"foo";
NSString *string2 = #"foobar";
// Compute the desired length
NSUInteger length = MAX(string1.length, string2.length);
// We will pad using this string
NSString *paddingString = #"0";
// Pad both strings to the same length
string1 = [string1 stringByPaddingToLength:length withString:paddingString startingAtIndex:0];
string2 = [string2 stringByPaddingToLength:length withString:paddingString startingAtIndex:0];
// Build two arrays containing the characters, percent escaped
NSMutableArray *charactersArray1 = [NSMutableArray arrayWithCapacity:string1.length];
NSMutableArray *charactersArray2 = [NSMutableArray arrayWithCapacity:string2.length];
for (NSInteger i = 0; i < string1.length; i++) {
[charactersArray1 addObject:[[string1 substringWithRange:(NSRange){ i, 1 }] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
[charactersArray2 addObject:[[string2 substringWithRange:(NSRange){ i, 1 }] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}
NSLog(#"String 1: %#\nString 2: %#", charactersArray1, charactersArray2);
The result will be
String 1: [ f, o, o, 0, 0, 0 ]
String 2: [ f, o, o, b, a, r ]
I figured out my problem, _input1 and _input2 were bad pointers and i had to fix it, sorry for all the confusion, in the end i got my code to work!
I want a string of all the characters of the alphabet randomized. Right now, I create a mutable array of the 26 characters, shuffle them with the exchangeObjectAtIndex: method and then add each character to a string that I return.
There has to be a better way to do this. Here is my code:
- (NSString *)shuffledAlphabet {
NSMutableArray * shuffledAlphabet = [NSMutableArray arrayWithArray:#[#"A",#"B",#"C",#"D",#"E",#"F",#"G",#"H",#"I",#"J",#"K",#"L",#"M",#"N",#"O",#"P",#"Q",#"R",#"S",#"T",#"U",#"V",#"W",#"X",#"Y",#"Z"]];
for (NSUInteger i = 0; i < [shuffledAlphabet count]; ++i) {
// Select a random element between i and end of array to swap with.
int nElements = [shuffledAlphabet count] - i;
int n = (random() % nElements) + i;
[shuffledAlphabet exchangeObjectAtIndex:i withObjectAtIndex:n];
}
NSString *string = [[NSString alloc] init];
for (NSString *letter in shuffledAlphabet) {
string = [NSString stringWithFormat:#"%#%#",string,letter];
}
return string;
}
Here's an efficient Fisher-Yates shuffle, adapted to your use case:
- (NSString *)shuffledAlphabet {
NSString *alphabet = #"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// Get the characters into a C array for efficient shuffling
NSUInteger numberOfCharacters = [alphabet length];
unichar *characters = calloc(numberOfCharacters, sizeof(unichar));
[alphabet getCharacters:characters range:NSMakeRange(0, numberOfCharacters)];
// Perform a Fisher-Yates shuffle
for (NSUInteger i = 0; i < numberOfCharacters; ++i) {
NSUInteger j = (arc4random_uniform(numberOfCharacters - i) + i);
unichar c = characters[i];
characters[i] = characters[j];
characters[j] = c;
}
// Turn the result back into a string
NSString *result = [NSString stringWithCharacters:characters length:numberOfCharacters];
free(characters);
return result;
}
This is the more efficient way to perform a correctly shuffled alphabet generation.
- (NSString *)shuffledAlphabet
{
const NSUInteger length = 'Z' - 'A' + 1;
unichar alphabet[length];
alphabet[0] = 'A';
for ( NSUInteger i = 1; i < length; i++ )
{
NSUInteger j = arc4random_uniform((uint32_t)i + 1);
alphabet[i] = alphabet[j];
alphabet[j] = 'A' + i;
}
return [NSString stringWithCharacters:alphabet length:length];
}
It uses the "inside-out" version of the Fischer Yates shuffle and avoids modula bias by generating the pseudorandom numbers with arc4random_uniform. Also, it requires a single allocation as all the permutations are performed in a temporary buffer.
Generating random numbers in Objective-C does this help?
*generate random number
*divide by 26 and take reminder
*index array[reminder]
You could pick random elements from the (remaining) alphabet while you build your string instead of shuffling it first:
NSMutableArray *alphabet = [NSMutableArray arrayWithObjects:#"A",#"B",#"C",#"D",#"E",#"F",#"G",#"H",#"I",#"J",#"K",#"L",#"M",#"N",#"O",#"P",#"Q",#"R",#"S",#"T",#"U",#"V",#"W",#"X",#"Y",#"Z", nil];
NSMutableString *result = [NSMutableString string];
NSUInteger numberOfLetters = alphabet.count;
for (NSUInteger i = 0; i < numberOfLetters; i++) {
int n = arc4random() % alphabet.count;
[result appendString:[alphabet objectAtIndex:n]];
[alphabet removeObjectAtIndex:n];
}
NSLog(#"%#", result);
This makes the code a bit shorter. Note also that using NSMutableString is more efficient than creating a new NSString each time a letter is added.