Is there anyway to do stringification in swift? , since there is no preprocessor it seems kind of difficult.
What I'd like to do is something similar to the following code.
// log a variable name and its value
#define LOGV(V) NSLog(#"%s = %#", #V, V);
NSString *myString = #"this";
LOGV(myString); // prints out -> "myString = ???"
After looking at dump it seems that there is no way of reflecting a variable name.
let myString = "this"
dump(myString, name:"myString", indent: 0 maxDepth: 0, maxItems: 1)
I also wanted to do the same thing in Swift,
so I recently wrote debug-logging util which stringifies variables at runtime instead (reading entire code!)
You might find this interesting.
https://github.com/inamiy/DebugLog
There is no way to do this in Swift. If you ABSOLUTELY want to do this, its always possible to run the C preprocessor over your Swift source.
Related
In iOS I have some confusion when calling a function.
-(void) function:(NSString*) str
{
selectedstring = str;
}
When calling the function.
When should I call like:
self.function = #"My name";
and
[self function:#"My name"]
What is the difference between (.) parameter and [ ]
in iOS function calling?
myVar = self.property is equivalent to myVar = [self property]
self.property = anotherVar is equivalent to [self setProperty:anotherVar]
Which you use is a matter of style.
Some people will tell you that the dot syntax should only be used for things that are actually defined as properties (with #property). I disagree with this. My opinion is that the dot syntax should be used whenever you're calling something that gets or sets a value, with minimal other side effects. Whether you have written the method yourself or synthesized a property to auto-generate it is not important: the important thing is whether it is related to getting and setting a value.
So myArray.count is fine, despite it not being a #property in the header file. But myURLConnection.start is not, since that doesn't return a value and is related to performing an action.
People do disagree with this. Some people don't like using dot syntax at all, since it could be confused with accessing the members of a struct (which also use .). Others are happy to use dot syntax for #propertys, but not for other methods.
Currently I am making a Calculator that allows the user to type out the formula they wish.
Ex. ((1+1)**9)+2)
This works just fine, I have used two methods for calculating this.
First:
answer = [[NSExpression expressionWithFormat:typeTo.text, nil] expressionValueWithObject:nil context:nil];
typeTo.text = [NSString stringWithFormat:#"%#", answer];
answerLabel.text = [NSString stringWithFormat:#"ANS { %# }", answer];
Second:
answer = [GCMathParser evaluate:typeTo.text];
Both of these calculate the problem without difficulty. But if the user types in:
(1+1)) [two brackets]
Both ways crash. This is one example of many different syntax errors. Is there a way to easily prevent this?
.
Additional info:
This is the way the second method catches the error:
#ifdef __COCOA_IMPLEMENTATION__
[NSException raise:#"Error in expression" format:#"error = %s", errStr];
#endif
THANKS :D
I haven't used either of those but based on the additional info, it may be throwing an NSException.
If that's the case, you can catch it and handle it. It looks like it might format a useful message telling you what's wrong with with expressions.
#try
{
// do work
}
#catch(NSException* ex)
{
// handle
}
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Exceptions/Tasks/HandlingExceptions.html
Also, look to see if those libraries offer functions that pass in a ref to NSError. If so, you can use that.
There's also DDMathParser which is supposed to be a modern math parser and it looks like it takes NSError. Might be worth a look.
http://github.com/davedelong/DDMathParser
I've seen this operator pop up quite a few times in example code in "Learn Objective C on the Mac."
I believe it's an operator in the C language which Objective C inherits.
I tried Googling and searching Stack Overflow and oddly nothing came up.
Does it have an English name?
It has to do with structures.
When we have a struct available locally on the stack, we access its members with the . operator. For example:
CGPoint p = CGPointMake(42,42);
NSLog(#"%f", p.x);
However, if we instead have a pointer to a structure, we have to use the -> operator:
CGPoint *p = malloc(1*sizeof(CGPoint));
p->x = 42.0f;
NSLog(#"%f", p->x);
free(p);
-> is not specific to Objective-C. It's a C operator.
Now that's cleared, it's the member access operator, equivalent to a pointer dereference and then using the dot operator on the result.
Say you had a struct like this:
typedef struct Person {
char *name;
} Person;
Person *jacob = malloc(1*sizeof(Person));
So this statement:
jacob->name = "Jacob";
Is equivalent to this statement:
(*jacob).name = "Jacob";
Of course, don't forget the free:
free(jacob);
In C
a->b
is a shortcut for
(*a).b
which is for dereferencing of members of a struct that is pointed to.
This is useful, because of . binds stronger than the dereferencing operator * . So by using -> you avoid having to use these ugly parentheses.
It's a member selection (or access) equivalent to a pointer de-reference (as pointed out in comments)
a->member is equivalent to (*a).member in C/C++
The same thing that it means in C. It can be used to access the instance variables of objects directly, but generally this is not the best practice. The dot notation you're referring to is a property, not the usual C dot notation.
It's the "indirect member access operator". It's a C operator, which both Objective-C and C++ inherited.
This
a->b
is equivalent to:
(*a).b
but is less typing. (The parens are necessary in the expanded form due to precedence of * and ..)
a->b is equivalent to (*a).b, and designates member b of the object pointed to by a.
In the C standard, it is called the "structure/union pointer operator," which isn't really the catchiest name.
It's all been said, it is a shortcut for accessing members of a struct pointer, but just a note to add that you can access ivars using the same syntax due to the way the Objective-C runtime works:
#interface Foo : NSObject {
NSString *something;
}
/* ... SNIP ... */
NSLog(#"something = %#", foo->something); // Where foo is an instance of the Foo class
This is handy when you need to access ivars that aren't exposed by methods; specifically when you need to implement copyWithZone: on your objects.
I have dozens of NSStrimgs that when the app loads I want to all be set to the same set. All of them. How can I do this without typing out every single one? Is there a shortcut method?
Thanks.
Also the problem is that Josh isn't specific enough about how he's using his dozens of strings... I think this would be better:
NSMutableArray *stringsArray = [NSMutableArray arrayWithCapacity:1];
NSString *tempStr = #"My unique string"; // Thanks Sven!
// Say you want a dozen strings
for (int i = 0; i < 12; i ++) {
[stringsArray addObject:tempStr];
}
// Now you can use them by accessing the array
[self doSomethingWithString:[stringsArray objectAtIndex:8]];
Instead of having dozens of strings that have the same value, could you make a single static global string and reference that? If you need to change it to separate values later, use instance variables that are initialized to the global string.
This sounds like your model is not very good at all. Since you want to initialize all of your strings to the same value they are obviously related and probably should be modeled as an array like iPhoneDevProf described. That makes other things a lot easier too, you can move other code that is repeated for every string into a loop.
If the value is known when you are compiling the code AND it is not going to change after subsequent application sessions then you can use a simple #define.
#define MY_DEFAULT_STRING #"THE DEFAULT STRING"
Now all you have to do is the following.
{
NSString *myString1 = MY_DEFAULT_STRING;
NSString *myString2 = MY_DEFAULT_STRING;
....
NSString *myStringN = MY_DEFAULT_STRING;
}
If all the strings are in the same code file, just put the define at the top. If the strings are in separate code files, then it could be put into your precompiled header. Having a constants file is usually better.
Using constant extern NSString would probably be more correct, but this is simple and easy to do.
I have the following define'd constant set up.
#define EndDateNotSpecified "None"
But I can't seem to evaluate it, I've tried
if (btnEndDate.titleLabel.text != EndDateNotSpecified) {
and
if (btnEndDate.titleLabel.text isEqualToString:EndDateNotSpecified) {
I get compiler problems with each.
You missed an # for the string, remember to add this to every string constant:
#define EndDateNotSpecified #"None"
Close, just missing brackets around the method call, like
if ([btnEndDate.titleLabel.text isEqualToString:EndDateNotSpecified]) {
And in the future, it generally helps if you tell us what the specific compiler error was.
In objective C, you have to call a method in [] so the second one should be:
if ([btnEndDate.titleLabel.text isEqualToString:EndDateNotSpecified]) {
Don't use this because it will not always give correct result when you only compare the NSString pointer object
if (btnEndDate.titleLabel.text != EndDateNotSpecified) {
Generally, I think you should learn the basic Objective-C, your code doesn't look like a obj-c code. No [], no #"" for String:(