Reputation: 658
I create an extension for UIView in Swift. Anyone knows how to import that file to my UIViewController?
I want to import the extension file in the controller file, in that way I can reuse the extension file. For example an structure like this:
UIViewExtension.swift
import UIKit
extension UIView {
var myVar : Float {
get {
return myVar
}
set (newMyVar) {
myVar = newMyVar
}
}
}
ViewController.swift
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var squareView: UIView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
squareView.myVar = 50
self.view.addSubview(squareView)
println("Offset: \(squareView.myVar)")
}
}
This is the error given by the compiler:
Command /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 254
Upvotes: 14
Views: 15573
Reputation: 1311
There several things going on here.
You can only add computed properties to an extension. This means that you do not actually have a myVar to assign to or read from. So when you access myVar
you are actually recursing infinitely. That is actually what the warning is alluding to (albeit in vague way):
warning: attempting to access 'myVar' within its own getter
return myVar
^
As far as I know, there is no way to add non-computed properties to a type using an extension. This is also true of Objective-C where the only way to actually store a property added to a class using a class extension is to use Objective-C object association via objc_getAssociatedObject
and objc_setAssociatedObject
from objc/runtime.h
.
Finally there is definitely a bug in the compiler if your extension's computed property has a setter. The minimum working example to reproduce the bug, which does not include recursion (by eliminating the access to myVar) and just ignore the value is:
import UIKit
extension UIView {
var myVar : Float {
get {
return 0
}
set {
}
}
}
Upvotes: 8
Reputation: 988
Using static in front of the property declaration seems to do the trick.
extension UIView {
static var myVar : Float {
get {
return myVar
}
set (newMyVar) {
myVar = newMyVar
}
}
}
Hope it helps!
Upvotes: -1
Reputation: 72
I encountered this issue as well. It appears that it is a compiler bug. The compiler seems to crash if you have computed properties in a standalone extension file. The workaround I have found is to create the extension in non-standalone file. So in this case you could move your extension into your ViewController.swift file. Like so:
import UIKit
extension UIView {
var myVar : Float {
get {
return myVar
}
set (newMyVar) {
myVar = newMyVar
}
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var squareView: UIView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
squareView.myVar = 50
self.view.addSubview(squareView)
println("Offset: \(squareView.myVar)")
}
}
Upvotes: 2
Reputation: 8214
After selecting the file in Xcode in the Project navigator on the left, make sure you check the app and test in the Target Membership section in the Inspector view on the right.
If it is not checked then it won't be included in the project and hence you will get the compile error.
Upvotes: 0