I busy rewriting an app in Swift and would like to convert the following macro to Swift code.
#define FLOG(format, ...) NSLog(#"%#.%# %#", [self class], NSStringFromSelector(_cmd), [NSString stringWithFormat:format, ##__VA_ARGS__])
How can I define this as a Swift function such that I can use if anywhere for debug logging purposes, or is there an alternate way to achieve the same thing?
The easiest way is probably to take advantage of string interpolation and use:
func FLOG(message:String, method:String = __FUNCTION__) {
println("\(method): \(message)")
}
Then you usage is similar to:
FLOG("Illegal value: \(value)")
Having the method argument default to __FUNCTION__ means that it will normally be replaced with the calling function name. Other automatic variables that you could use include __FILE__, __LINE__ and __COLUMN__. Unfortunately __PRETTY_FUNCTION__ is no longer available.
If you want more control over the formatting of the message than string interpolation allows, take a look at this question which demonstrates simplifying access to printf-style formatting in Swift, and would let you do:
FLOG("Illegal value: %x" % [value])
See also this post from Apple that addresses using __FILE__ and __LINE__ in assert
Apple's answer to the removal of macros and something new to replace them is that nothing like macros will be available in swift. The closest you can get is to replace #define with a global let variable.
Example: instead of #define CONSTANT 0 you can write let CONSTANT = 0
Whereas, if you want to pass arguments inside a macro, that feature will no longer be available as considered bad programming practice. What you can do instead is create a function.
Related
Can anyone explain how I'm supposed to use the method 'getVersion' for CGPDFDocument in Swift?
Apple's documentation gives:
func getVersion(majorVersion: UnsafeMutablePointer<Int32>,
minorVersion: UnsafeMutablePointer<Int32>)
"On return, the values of the majorVersion and minorVersion parameters are set to the major and minor version numbers of the document respectively."
So I supply two variables as arguments of the function, and they get filled with the values on exit? Do they need to point to something in particular before the method is called? Why not just type them as integers, if that's what the returned values are?
You use it like this:
var major: Int32 = 0
var minor: Int32 = 0
document.getVersion(majorVersion: &major, minorVersion: &minor)
print("Version: \(major).\(minor)")
The function expects pointers, but if you pass in plain Int32 variables with the & operator, the Swift compiler is smart enough to call the function with pointers to the variables. This is documented in Using Swift with Cocoa and Objective-C: Interacting with C APIs.
The main reason the function works like this is probably that it's a very old C function that has been imported into Swift. C doesn't support tuples as return values; using pointers as in-out parameters is a way to have the function return more than one value. Arguably, it would have been a better design to define a custom struct for the return type so that the function could return the two values in a single type, but the original developers of this function apparently didn't think it was necessary — perhaps unsuprisingly, because this pattern is very common in C.
Is it possible to overload constants in Perl 6? Here is the Perl 5 example I'm looking at.
In particular I would like to get a string of the literal value used, e.g. if the code was
my $x = .1e-003 ;
I need ".1e-003" instead of 0.0001.
I just added such a module:
https://github.com/FROGGS/p6-overload-constant
USAGE:
use v6;
sub decimal { $^a.flip }
use overload::constant &decimal;
say .1e-003 # "300-e1."
You can change how a value stringifies by mixing in an appropriate role with the but operator, ie
0.0001 but role { method Str { ".1e-003" } }
which can be shortened to
0.0001 but ".1e-003"
Note that providing a method Stringy instead of Str might actually be more appropriate from a semantic point of view, but I do not think Rakudo as of today handles that distinction correctly in all case.
I don't think anything like overload::constant exists in the spec or the existing libraries, but it should be possible to write it using macros by looking in the AST for the type of literal that you're interested in, and replacing it with an object constructor or whatever you need.
Cleaner, perhaps, would be to wrap each one of these constants in a macro invocation, instead of spanning the whole program with one.
I have seen in many iOS header's that (^) is utilized, and I have never come across the reasoning as of why that sign is being used. Would anyone might like to enlighten into this?
Thanks.
Those often indicate "blocks". See the Blocks Programming Topics.
Alternatively, if you watch the beginning of WWDC 2012 session 712, they also walk you through blocks with a touch of historical context.
It signifies a block. A block is a syntax that allows you to create a callback function, and pass it into a method as a parameter. In other languages this is similar to a closure, a lambda, or an anonymous class.
For example a parameter that lists:
void(^)(NSString *myStr)
is expecting you to pass in a block/function that returns void, and takes in an NSString pointer.
You can create a block, based on the expected parameters declared in the method, with this syntax:
^(<Parameters>) { <Body> }
For example, a method that is expecting a block parameter might look like this:
-(void)doSomething:(void(^)(NSString *myStr))theBlock;
...and could be called like this:
[self doSomething:^(NSString *myStr) { NSLog(#"The String is: %#", myStr); }];
Your block will be called back from doSomething: just like a function, using the parameter name:
-(void)doSomething:(void(^)(NSString *myStr))theBlock {
theBlock(#"Hello!");
}
...which would display:
The String is: Hello!
The ^ character is used for blocks, in particular, block parameters.
If you're asking why the character '^' for use in blocks, it's because there's relatively few characters left that:
Are available on all typical keyboards.
Could be used at all - i.e. aren't already significant in the language and would conflict.
Don't look stupid.
That actually narrows it down to only two or three, and of those '^' was chosen because, well, because.
There's probably a record of this on the llvm.org mailing lists and so forth, if you want to pore over the discussion in detail.
You could also look at the minutes from the C++11 committee meetings on lambdas, which went through basically the same process.
I have a constant in one class that I want to access from another.
I want to access these:
#define kStateRunning 1
#define kStateGameOver 2
#define kStateMenu 3
which are in my GameController.h from Level1.m. In Level1.h I have #class GameController as well as an import in the implementation file.
I tried searching for an answer, but I'm not sure if I'm wording all this correctly.
If you use #define myConstant, myConstant will be known since you import your file. Define them at the beginning of your GameController.h between the import and the #Interface for example.
Then if you import GameController.h in one of your other files (let's take Level1.m for example). You can use it, without prefixing it. Just use myConstant
I wouldn't use #define as you lose any checking from the compiler. Generally you use a constant to avoid using magic values throughout your code that can be spelt wrong or typed wrong.
In the Apple docs for Coding Guidelines they tell you how you should approach each type of constant.
For simple integers like you have, they suggest enums are the best option. They are used extensively in the Apple frameworks so you know they are good.
You would still need to define it in your header.
e.g. (Use your own prefix instead of PS)
typedef enum {
PSGameStateRunning = 1,
PSGameStateGameOver,
PSGameStateMenu,
} PSGameState;
This also has the advantage of being a type that you can pass into/return from functions if you require
Example: I want to do this:
METHODNAME(5) {
// do something
}
which results in:
- (void)animationStep5 {
// do something
}
Is there any way to do this? Basically, what I need is a way to generate a real source code string before the program is compiled, so the compiler does see - (void)animationStep5...
Or maybe there's something different than a macro, which can help here to auto-generate method names (not at run-time)?
As was already answered here, the objective-C preprocessor is very close to the C one.
You should have a look at the examples posted there, and have a look at C proprocessor. You will simply have to use the ## syntax of the preprocessor, to concatenate the method name, and the number you want.
You can use the concatenation operator
#define METHODNAME(i) -(void)animationStep##i
you can call it like
METHODNAME(5){}
This expands to
-(void)animationStep5{}
Assuming the objective-c preprocessor behaves the same as the standard C one, you can use something like:
#define PASTE(a, b) a##b
#define METHODNAME(n) PASTE(animationStep,n)
to join the required bits together. This means that
METHODNAME(5)
gets translated to
animationStep5
(you may need to add the "void" from your question to the macro definitino depending on exactly what it is you need to do).