How do I make class methods / properties in Swift?
They are called type properties and type methods and you use the class
or static
keywords.
class Foo {
var name: String? // instance property
static var all = [Foo]() // static type property
class var comp: Int { // computed type property
return 42
}
class func alert() { // type method
print("There are \(all.count) foos")
}
}
Foo.alert() // There are 0 foos
let f = Foo()
Foo.all.append(f)
Foo.alert() // There are 1 foos
Correct way to initialize class property with method
As @vadian told lazy is a good way of doing it. But I want to add something.
I think you need to make your height
and width
private, to prevent changing them from outside, lazy block will be called once and if you will change for ex. height
from 10 to 100 you board calculation will not be called. If you need to change your game settings after initializing it so I will suggest another option to do it.
class Game {
var height: Int {
didSet {
board = self.updateGameBoard(height: height,
width: width)
}
}
var width: Int {
didSet {
board = self.updateGameBoard(height: height,
width: width)
}
}
lazy var board: [[String]] = {
return updateGameBoard(height: height, width: width)
}()
init(height: Int, width: Int) {
self.height = height
self.width = width
}
private func updateGameBoard(height: Int,
width: Int) -> [[String]] {
var gameBoard: [[String]] = []
//working with width and height props from above
//filling the board and returning
return gameBoard
}
}
This will allow you to change update the board reactive from outside by changing height
or width
How to setup a class property in objective C?
Since Xcode 8 you can define a class property in the header file of YourClass, using the "class" identifier like:
@interface YourClass : NSObject
@property (class, strong, nonatomic) NSTimer *timer;
@end
To use the class property in class methods in your implementation you need to asign a static instance variable to your class property. This allows you to use this instance variable in class methods (class methods start with "+").
@implementation YourClass
static NSTimer *_timer;
You have to create getter and setter methods for the class property, as these will not be synthesized automatic.
+ (void)setTimer:(NSTimer*)newTimer{
if (_timer == nil)
_timer = newTimer;
}
+ (NSTimer*)timer{
return _timer;
}
// your other code here ...
@end
Now you can access the class property from all over the app and other methods with the following syntax - here are some examples:
NSTimeInterval seconds = YourClass.timer.fireDate.timeIntervalSinceNow;
[[YourClass timer] invalidate];
You will always send messages to the same object, no problems with multiple instances!
Please find an Xcode 11 sample project here: GitHub sample code
Swift 5 reflection get list of class properties and call them
From the docs:
Describes the instance methods implemented by a class.
constMethod1
and constMethod2
are computed class properties, which translates to class methods in Objective-C. So they won't be returned by class_copyMethodList
. But fear not, the docs also say:
To get the class methods of a class, use
class_copyMethodList(object_getClass(cls), &count)
.
So you can do:
let methodList = class_copyMethodList(object_getClass(MyClass.self), &methodCount)
To call it, you can use perform
:
if crtMethodStr.hasPrefix("const") {
let result = MyClass.perform(method_getName(unwrapped!))!.takeUnretainedValue()
print(result)
}
Swift.... Class method vs. Instance method
If you're asking a question you should reduce your code to a minimum, discarding unnecessary details.
You probably want something like this:
class MyClass {
let x = MyClass.getStuff()
static func getStuff() -> Int {
return 0
}
}
However your method getWallImages()
can't do something like this, because it's returning the result asynchronous, which means you get the result much later after the function has returned.
You could do something like this though (this is how I'd be doing it):
class MyClass {
var x : Int? {
didSet {
if let x = x {
// Do something with x, here it's assigned
} else {
// x was set to nil, something failed
}
}
}
init() {
getStuffAsynchronous()
}
func getStuffAsynchronous() {
// Do your query stuff here, assign x to your objects to invoke the didSet
x = 0
// If it fails somehow, assign set x to nil
// if fail {
// x = nil
// }
}
}
iOS - How to call a method without initialising the class in Swift?
You need to make the function either a class
or static
function. For example:
extension UIColor {
/** Set the color to white. */
class func white() -> UIColor {
return UIColor.whiteColor()
}
}
You can also use the word static
instead of class.
Passing a class's properties to class method selectively in Swift
You are on the right track of using inout
, just do not forget to have an &
, at calling.
So, declare the function like this:
func updateBar(_ bar1: inout [Int], _ bar2:[Int])
And call like this:
updateBar(&bar.one, bar.two)
I've also put some code:
struct Bar
{
var one:[Int] = []
var two:[Int] = []
var tri:[Int] = []
}
class foo
{
var bar = Bar()
func setupBar()
{
bar.one = [1]
bar.two = [2,2]
bar.tri = [3,3,3]
}
//bars are updated here
func updateBars()
{
updateBar(&bar.one, bar.two) //...here...
updateBar(&bar.two, bar.tri) //...here...
}
//Bar1 should be concatenated with Bar2, and thus Bar1 will be updated.
func updateBar(_ bar1: inout [Int], _ bar2:[Int]) //...here...
{
bar1.append(contentsOf: bar2)
}
}
let f = foo()
f.setupBar()
f.updateBars()
Swift documentation: instance/type property/method notation
Unfortunately Swift does not have an official or widely-accepted notation to distinguish type properties/methods and instance properties/methods with type name prefixed form.
(So, usual Swift programmers (even expert) cannot understand what you are asking.)
Type name prefixed form is actually used in the Swift book, but not so often.
As far as I checked:
In some parts, type property is referred to in a form like
UInt32.max
, but as you see this is just using actual notation valid as Swift expression.In some other parts, type method is referred to as a form like
LevelTracker.unlock(_:)
, but this also is a valid expression in Swift and I'm not sure Apple is using this as a documentation notation for type method. I cannot find an example in the Swift book with a short glance, but initializers are often referred to in a form likeString.init(data:encoding:)
and this is also a valid expression in Swift.For other cases, instance methods or properties are referred to as
instanceVar.methodName(_:)
orinstanceVar.propertyName
, of courseinstanceVar
appears in a nearby code snippet and is not a type name, this actually is not what you are looking for.
And as you already know, in Apple's official references, methods or properties are shown with heading Instance method, Type method , Instance Property or Type Property. Or prefixed with class/static var/let
, class/static func
, var/let
or func
.
I cannot find an example with a very short survey, but some articles (including Apple's) may be referring to an instance method also in a form TypeName.methodName(_:)
(or instance property as well.) Seems Swift community thinks distinguishing type members and instance members is not important.
I could not take much time, but seems it is obvious that
Swift does not have an official or widely-accepted notation to distinguish type properties/methods and instance properties/methods with type name prefixed form.
Maybe you need to write something like instance method Array.append(_:)
to represent Array#append(_:)
.
(To note, Array.append(_:)
is also a valid expression in Swift.)
Related Topics
Programmatically Screenshot | Swift 3, Macos
Swift: Failing to Copy Files to a Newly Created Folder
Compile Error in Swift 4 on Parameter Passing
Multiple Type Constraints in Swift
Delete Data from Coredata Swift
How to Get Directory Size with Swift on Os X
Obervableobject Being Init Multiple Time, and Not Refreshing My View
Xcode 9 and Xcode 10 Giving Different Results, Even with Same Swift Version
Swift Date(Byadding:To:) Returns Nil for Trivial Calculation in Repl
How to Add Material to Modelentity Programatically in Realitykit
How to Configure Contextmenu Buttons For Delete and Disabled in Swiftui
Swift3 Optionals Chaining in If Conditions Bug
App Tracking Transparency Dialog Does Not Appear on iOS
@Noescape Attribute in Swift 1.2
How to Create a Generic Array Extension That Sums Number Types in Swift
Dynamic Row Hight Containing Texteditor Inside a List in Swiftui
Simpliest Solution to Check If File Exists on a Webserver. (Swift)