I have a C code:
static __inline__ __attribute__((__always_inline__))
__attribute((swift_name("Test.init()")))
test_t test_init(void) { /* ... */ }
And test Swift code:
let test = Test()
The code is compiled, but function test_init not call.
If I add test argument and call init with him, my method * test_init * is called.
For structures imported from C the compiler creates an init() initializer which takes no arguments and sets all members to zero. For example
__attribute((swift_name("Test")))
typedef struct {
int a;
} test_t;
is imported to Swift as
public struct Test {
public var a: Int32
public init()
public init(a: Int32)
}
as one can see with "Navigate -> Jump to Generated Interface" in Xcode.
You can create additional init methods in C, but you cannot replace
existing init methods.
(One could argue that the compiler should as least warn that the
C function with the Swift name "Test.init()" will be ignored in Swift, so you might consider to file a bug report.)
If you want to define another init method taking no arguments in C
then you have to give it a dummy Void argument:
__attribute((swift_name("Test.init(v:)")))
static __inline__ __attribute__((__always_inline__))
test_t test_init(void) {
test_t t = { 3 };
return t;
}
and call it as
let test = Test(v: ())
print(test) // Test(a: 3)
Related
If the postfix operator of a custom function is declared at file scope - as in my previous post - there must be a way to access such a function from another Swift 3 file in the same Xcode project.
Apple’s documentation on custom functions states that “New operators are declared at a global level …“ so I can presume the creators of Swift 3 would consider it important for a custom function to be accessed globally. But for a novice in Swift it is not self-evident how I would do this.
Based on code in my previous accepted answer (here) what would I need to do so a custom function can be accessed from another file elsewhere in the project ?
FINAL EDIT
The solution is embarrassingly simple (see accepted answer) and hopefully other Swift novices may also find it useful.
A postfix operator % is declared globally while an Extension of Int reads an Int variable from another file. Extensions of Double and CGFloat as well as Int are also possible.
CustomOperators.swift
import UIKit
postfix operator %
extension Double {
static postfix func % (n: Double) -> Double {
return Double(n) / 100
}
}
extension Int {
static postfix func % (n: Int) -> Double {
return Double(n) / 100
}
}
extension CGFloat {
static postfix func % (n: CGFloat) -> Double {
return Double(n) / 100
}
}
ViewController.swift
import UIKit
class ViewController: UIViewController {
let test1: Double = 93.7
let test2: Int = 80
let test3: CGFloat = 70
override func viewDidLoad() {
super.viewDidLoad()
print(test1%) // prints '0.937'
print(test2%) // prints '0.8'
print(test3%) // prints '0.7'
}
}
Thanks marosoiae, and also Martin R and unniversal for your input.
EDIT 2
Martin R’s comments prompted me to try a further example with my custom postfix function defined in Utils but in file scope rather than as a static postfix function. Utils becomes an empty class for custom functions all defined in file scope outside the class.
import UIKit
class ViewController: UIViewController {
let value: Int = 25
override func viewDidLoad() {
super.viewDidLoad()
example1()
example2()
}
func example1() {
// 1. call to a function in Utils with an explicit value
// and nothing returned from Utils.
// Note this uses literal postfix syntax i.e. 25%
Utils.25%
// Debug message:
// Type 'Utils' has no member '25'
}
func example2() {
// 2. call to a function in Utils with an argument
// declared in UIViewController and nothing returned from Utils
Utils.(Int: value)%
// Debug message
// Expected member name following '.'
}
}
Utils.swift now compiles but from debug messages that Xcode reports with both examples, it is clear that the token '%' is expected immediately following the '.'.
Even without returning a variable from Utils.swift, this is obviously not how to call a postfix function in Utils.swift from a file elsewhere in the project. My question remains: how would I do it ?
EDIT 1
At this point it might help to include some code so I created a class with static functions, following the syntax (as far as possible) used in Unniversal's answer. I decided to try static functions if these help avoid cluttering the global scope with methods that should be owned by a class/struct.
File 1 - Utils
import UIKit
postfix operator %
class Utils {
static func yourFunction(){
//Do your stuff here
}
static func yourFunction1(value: Int) {
print(value)
}
static postfix func % (percentage: Int) -> Double {
return (Double(percentage) / 100)
}
}
The static function % reports
Member operator '%' must have at least one argument of type 'Utils'
which I’d expect to disappear once an argument is supplied from another file.
The following code shows four ways I tried to supply an argument to static functions in Utils. I ran the project with one example at a time
File 2 - UIViewController
import UIKit
class ViewController: UIViewController {
let value: Int = 25
var percentage = Double()
override func viewDidLoad() {
super.viewDidLoad()
// example1()
// example2()
// example3()
// example4()
}
func example1() {
// 1. call to a function in Utils with no argument and no return (i.e. suggested answer)
Utils.yourfunction()
// Debug messages:
// Type 'Utils' has no member 'yourfunction'
// Did you mean 'yourFunction'?
// Did you mean 'yourFunction1'?
}
func example2() {
// 2. call to a function in Utils with argument and no return
Utils.yourfunction1(Int: Int)
// Debug messages:
// Type 'Utils' has no member 'yourfunction'
// Did you mean 'yourFunction'?
// Did you mean 'yourFunction1'?
}
func example3() {
// 3. call to a function in Utils with argument and returning a value for percentage
Utils.%() {
return Int(percentage)
}
// Debug message:
// Use of unresolved operator '.%'
}
func example4() {
// 4. call to a function in Utils with argument and returning a value for percentage
percentage = Utils.%(Int: value) -> Int {
return Int(percentage)
}
// Debug messages:
// Use of unresolved operator '.%'
// Expected type before '->'
// Expected type after '->'
}
}
As far as I can see, static functions Utils.yourFunction and Utils.yourFunction1 can’t be accessed from outside Utils, as shown in example 1 and 2. And the postfix operator % seems to cause Xcode to report Use of unresolved operator ‘.%’, as shown in example 3 and 4. However these problems might be the way I adapted the syntax used by Unniversal.
Any function declared at file scope will have the implicit scope internal and will be visible in the rest of the project/module.
I recommend reading the access control guide for more information.
Edit:
I'm still not sure what you're trying to do, but it looks like you are mixing global functions with static methods and custom operators.
If what you want is to declare a custom operator that you can use in any other file in the project, the solution is in the documentation that you linked in your question.
So this is what you need to declare a custom % (as you defined it) for the Int type:
CustomOperators.swift
postfix operator %
extension Int {
static postfix func % (n: Int) -> Double {
return Double(n) / 100
}
}
main.swift
print(90%) //outputs "0.9"
That's all there is to it. You simply declare the operator globally: postfix operator % and you define the operator function as a static method in a extension on the Int type.
Now you can use your new operator in other files (like I did in main.swift).
If you want a function to be accessed globally I would recommend to create a class that has static functions. For example
class Utils {
static func yourFunction(){
//Do your stuff here
}
}
To use it :
Utils.yourfunction()
Is there an example of how dispatch_once should be used in Swift? (Preferably one from Apple.)
Note: In this case, I'm not using it for a singleton; I want to run arbitrary code exactly once.
Update: I'm mainly interested in the convention recommended when using this in an instance method, but usage in a class method, function, and in the global context would be useful for completeness sake.
dispatch_once_t is type alias (Int). Header documentation:
/*!
* #typedef dispatch_once_t
*
* #abstract
* A predicate for use with dispatch_once(). It must be initialized to zero.
* Note: static and global variables default to zero.
*/
typealias dispatch_once_t = Int
And here's the quote from dispatch_once documentation:
The predicate must point to a variable stored in global or static
scope. The result of using a predicate with automatic or dynamic
storage (including Objective-C instance variables) is undefined.
Token variable must be stored in global / static scope and must be initialized to zero, which leads to this code:
import Foundation
var token: dispatch_once_t = 0
dispatch_once(&token) { () -> Void in
print("Called once")
}
It doesn't work if you omit = 0 (token initialization), because compiler yields error Address of variable 'token' taken before it is initialized despite the fact that statics and globals default to zero. Tested in Xcode 7B2.
More examples based on comment. If you're inside class method you have several possibilities.
You can't declare static property inside method otherwise compiler yields Static properties may only be declared on a type error. This doesn't work:
class func doItOnce() {
static var token: dispatch_once_t = 0
...
}
Must be declared on a type. This was introduced in Swift 1.2 (Xcode 6.3 IIRC).
“static” methods and properties are now allowed in classes (as an
alias for “class final”). You are now allowed to declare static stored
properties in classes, which have global storage and are lazily
initialized on first access (like global variables). Protocols now
declare type requirements as “static” requirements instead of
declaring them as “class” requirements. (17198298)
So, what we can do if we don't like globals?
Static variable on a type
class MyClass {
private static var token: dispatch_once_t = 0
class func doItOnce() {
dispatch_once(&token) {
print("Do it once")
}
}
}
Static in a method wrapped in struct
Don't like static property on yur class? Would like to have it in your method? Wrap it in struct like this:
class func doItOnce() {
struct Tokens { static var token: dispatch_once_t = 0 }
dispatch_once(&Tokens.token) {
print("Do it once")
}
}
Actually I'm not aware of any Apple recommendation, best practice, ... how to do it for dispatch_once. Simply use whatever you like most, feels good to you and just meet criteria global / static scope.
For those of you who are curious, for me this approach has been useful for this purpose:
class SomeVC : UIViewController {
private var token: dispatch_once_t = 0
public override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
dispatch_once(&token) { () -> Void in
self.doSomethingOnce()
}
}
}
By not declaring a static var it has the expected behaviour. That being said, this is definitely NOT RECOMMENDED for any serious project, since in the Docs (as your well said) it states:
The predicate must point to a variable stored in global or static scope. The result of using a predicate with automatic or dynamic storage (including Objective-C instance variables) is undefined.
If we don't want to run into any future weird bugs and undefined behaviour I would just stick to what Apple says. But it's still nice to play around with these things, isn't it? =)
the robertvojta's answer is probably the best. because i try always to avoid import Foundation and use 'pure' Swift solution (with Swift3.0 i could change my opinion), I would like to share with you my own, very simple approach. i hope, this code is self-explanatory
class C {
private var i: Int?
func foo()->Void {
defer {
i = 0
}
guard i == nil else { return }
print("runs once")
}
}
let c = C()
c.foo() // prints "runs once"
c.foo()
c.foo()
let c1 = C()
c1.foo() // prints "runs once"
c1.foo()
class D {
static private var i: Int?
func foo()->Void {
defer {
D.i = 0
}
guard D.i == nil else { return }
print("runs once")
}
}
let d = D()
d.foo() // prints "runs once"
d.foo()
let d2 = D()
d.foo()
I'd like to logically organize class properties to signify that they are one logical unit and to distinguish them from other class properties that are less tightly related.
I thought of doing this using a struct within my class. However, it seems that I can't call class methods from the struct property setters. I get what seems to be an inappropriate compile error: "missing argument for parameter #1 in call"
This seems to be different from calling method from struct in swift
where the function is within the struct. In my case, the methods are generic and don't just apply to my struct but to all class properties. Therefore, I don't want to move them within the struct.
Do you have ideas on how to organize properties into tight(er) logical units within classes?
class MyClass {
struct MyStruct {
static var aVarInMyStruct: String? {
didSet {
anotherVarInMyStruct = foo() // This gives compile error "missing argument for parameter #1 in call"
}
}
static var anotherVarInMyStruct: String?
}
func foo() {
println("I am foo()")
}
}
The inner type MyStruct knows nothing about its outer type MyClass. So there is no foo function to call from MyStruct. To better organize your code I suggest you to use // MARK: - whatever this section is comments. Types are not here to organize codes. Types are here to create right abstractions for the program.
I fix your bug:
class MyClass {
struct MyStruct {
static var aVarInMyStruct: String? {
didSet {
anotherVarInMyStruct = MyClass.foo() // This gives compile error "missing argument for parameter #1 in call"
}
}
static var anotherVarInMyStruct: String?
}
static func foo()->String {
println("I am foo()")
return "it is ok"
}
}
I want to call a function in initializer, but i couldn't do it
class someclass {
var a : Int
var b : Int
init() {
self.a = 5
self.b = 4
func printx () {
println("you called the function")
}
printx()
}
}
var ab = someclass()
Is it posible to do that something like ab.init().printx
And
Will this printx() function execute when i initialize with someclass()
For your questions: No - you can't reference your printx from outside of init and Yes - your printx will execute when init is called. In Swift 1.2:
20> class Bar {
21. var ping : Int
22. init () {
23. ping = 1
24. func bar () { println ("bar") }
25. bar()
26. }
27. }
28> Bar()
bar
$R4: Bar = {
ping = 1
}
Defining your printx in init is perfectly viable and you should demand that it works (and it does). Having lexically contained function definitions in Swift is critically important. Now, if the language could allow the function name to be recursively visible...
Maybe you would do something like this?
class someclass {
var a : Int
var b : Int
func printx () {
println("you called the function")
}
init() {
self.a = 5
self.b = 4
printx()
}
}
var ab = someclass()
ab.printx()
Consider you never call init() writing it but just with someClass()
This question simply demonstrates a lack of understanding when it comes to scope.
The function printx() is not a method on the class SomeClass, but it a function scoped within the particular init() method you've defined.
As written, printx() will execute (and will print) when you call the init() method:
See the box in the right pane at the top? That's showing us all of the console output from our playground, exactly as it would display if we ran this otherwise.
However, we cannot now call ab.printx() because as I stated earlier, printx() is not a member of the class SomeClass. If we want to call printx() on instances of SomeClass, we must then define it as an instance method of the class (and if we still want to call it in init, we can).
Calling a method from its name (in a String format) can be sometimes useful.
In Swift it is recomended to change behavior and to use closures to do something "dynamically", so for example you can have a dictionary of functions, with the name as the key, and the implementation as the value.
However, sometimes you want to simply know "how to do it", and this is the reason of this question.
So, how to call dynamically a Swift method starting from it's name as string?
In Objective C it was simple:
[self performSelector:NSSelectorFromString(#"aSelector")];
But performSelector is banned in Swift
Is there any alternative?
In Swift, you should use closures and change your approach.
However, if you want to use performSelector to dynamically call a method given only it's String signature, altough it's not supported natively, I've found how to do it.
It is possible to create a C alternative to performSelector that:
works even on native swift classes (non objective-c)
takes a selector from string
However it's not so straightforward to implement a complete version of it, and it's necessary to create the method in C.
in C we have dlsym(), a function that returns a pointer to a function given the char symbol.
Well, reading this interesting post:
http://www.eswick.com/2014/06/inside-swift/
I've learned a lot of interesting things about swift.
Swift instance methods are plain functions with a specific signature, like this
_TFC14FirstSwiftTest12ASampleClass13aTestFunctionfS0_FT_CSo8NSString
where the "self" value is passed as the last parameter
in short you can call it directly from the c side without any kind of bridging, it is sufficient to rebuild the correct function signature.
In the signature above, there is the name of the project (FirstSwiftTest) and the lenght (14), the name of the class (ASampleClass) and the lenght (12), the name of the function (aTestFunction) and the lenght (13), then other values as the return type ecc ecc. For other details look at the previous link
The function above, is the representation of this:
class ASampleClass
{
func aTestFunction() -> NSString
{
println("called correctly")
return NSString(string: "test")
}
}
Well, on the c side, I was able to create this function
#include <stdio.h>
#include <dlfcn.h>
typedef struct objc_object *id;
id _performMethod(id stringMethod, id onObject)
{
// ...
// here the code (to be created) to translate stringMethod in _TFC14FirstSwiftTest12ASampleClass13aTestFunctionfS0_FT_CSo8NSString
// ...
id (*functionImplementation)(id);
*(void **) (&functionImplementation) = dlsym(RTLD_DEFAULT, "_TFC14FirstSwiftTest12ASampleClass13aTestFunctionfS0_FT_CSo8NSString");
char *error;
if ((error = dlerror()) != NULL) {
printf("Method not found \n");
} else {
return functionImplementation(onObject); // <--- call the function
}
return NULL
}
And then called it on the swift side
let sampleClassInstance = ASampleClass()
println(_performMethod("aTestFunction", sampleClassInstance))
The function resulted in these statement printed on the log:
called correctly
test
So it should be not so difficult to create a _performMethod() alternative in C that:
creates automatically the function signature (since it seems to have a logic :-)
manages different return value types and parameters
EDIT
In Swift 2 (and maybe in Beta3, I didn't try) It seems that performSelector() is permitted (and you can call it only on NSObject subclasses). Examining the binary, It seems that now Swift creates static functions that can be specifically called by performSelector.
I created this class
class TestClass: NSObject {
func test() -> Void {
print("Hello");
}
}
let test = TestClass()
let aSel : Selector = NSSelectorFromString("test")
test.performSelector(aSel)
and now in the binary I find
000000010026d830 t __TToFC7Perform9TestClass4testfT_T_
At this time, I don't understand well the reasons behind this, but I'll investigate further
You could call a method from a String this way:
let foo = <some NSObject subclass instance>
let selectorName = "name"
foo.perform(Selector(selectorName))
It is available only when your foo class is subclass of NSObject
swift3 version
class MyClass:NSObject
{
required public override init() { print("Hi!") }
public func test(){
print("This is Test")
}
public class func static_test(){
print("This is Static Test")
}
}
if let c: NSObject.Type = NSClassFromString("TestPerformSelector.MyClass") as? NSObject.Type{
let c_tmp = c.init()
c_tmp.perform(Selector("test"))
c.perform(Selector("static_test"))
}