How to Make Class Methods/Properties in Swift

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 like String.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(_:) or instanceVar.propertyName, of course instanceVar 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



Leave a reply



Submit