What's the difference between class methods and instance methods in Swift? - swift

protocol NoteProtocol {
var body: NSString? { get set }
var createdAt: NSDate? { get set }
var entityId: NSString? { get set }
var modifiedAt: NSDate? { get set }
var title: NSString? { get set }
// class methods
class func insertNewNoteInManagedObjectContext(managedObjectContext: NSManagedObjectContext!) -> NoteProtocol
class func noteFromNoteEntity(noteEntity: NSManagedObject) -> NoteProtocol
// instance methods
func update(#title: String, body: String)
func deleteInManagedObjectContext(managedObjectContext: NSManagedObjectContext!)
}
Hi
This is a piece of code I found on GitHub. In this protocol, what is the main difference between class methods and instance methods? How they are defined?
Can anyone help me?

Some text from the documentation:
Instance Methods
Instance methods are functions that belong to instances of a particular class, structure, or enumeration. They support the functionality of those instances, either by providing ways to access and modify instance properties, or by providing functionality related to the instance’s purpose.
ie. An Instance of the class has to call this method. Example :
var a:classAdoptingNoteProtocol=classAdoptingNoteProtocol()
a.update()
Class Methods
Instance methods, as described above, are methods that are called on an instance of a particular type. You can also define methods that are called on the type itself. These kinds of methods are called type methods. You indicate type methods for classes by writing the keyword class before the method’s func keyword, and type methods for structures and enumerations by writing the keyword static before the method’s func keyword.
They are what are called as Static methods in other languages.To use them, this is what I would do:
var b=classAdoptingNoteProtocol.noteFromNoteEntity(...)
This will return a instance of a class which adopts NoteProtocol. ie. you don't have to create a instance of the class to use them.

Below the definition of instance methods and class methods (called type methods in Swift).
For more details you can browse the method section of the Swift documentation
Instance methods:
Instance methods are functions that belong to instances of a particular class, structure, or enumeration. They support the functionality of those instances, either by providing ways to access and modify instance properties, or by providing functionality related to the instance’s purpose. Instance methods have exactly the same syntax as functions
Type methods:
Instance methods, as described above, are methods that are called on
an instance of a particular type. You can also define methods that are
called on the type itself. These kinds of methods are called type
methods. You indicate type methods for classes by writing the keyword
class before the method’s func keyword, and type methods for
structures and enumerations by writing the keyword static before the
method’s func keyword.
Basically you can call type method (class method) without instance:
var myNoteProtocol = NoteProtocolAdoptImplClass.noteFromNoteEntity(...);
While you need to instantiate for instance methods:
var myNoteProtocol = NoteProtocolAdoptImplClass()
myNoteProtocol.update(...)

Related

Swift Design Choice - Protocol or Class? (mimicking Java's Abstract Class)

I'm making Tetris. What is the best solution for shared code amongst the pieces? A class, protocol, or something else?
Tetrimino template capabilities:
func moveDown()
func rotateRight() // based on data table
func rotateLeft() // based on data table
Each type of piece can rotate and move, but the way it rotates is determined by unique data tables. The data tables are the same between all instances of that piece (e.g. all long pieces rotate in the same way), and there is mainly shared functionality upon initialization.
It would make sense to use a protocol with a static variable for the data tables, and a default constructor that is run by conforming classes before running their unique code.
However, with a protocol, the static variables cannot be overridden, nor can a base initializer be provided that conforming classes can add onto. But if I use a class to get around these problems, then Tetrimino instances can be made, when it should just be a template.
What's the best design pattern for this?
Using a protocol with default implementations as your abstraction layer can work for your requirements.
You can declare the dataTable as a static requirement and then from conforming classes, you can make the variable a class variable in case it's computed and you want it to be overridable from subclasses or if it's a stored property, then subclasses can change its value even when it's static (stored properties need to be static anyways).
As for sharing common initialisation code, you can add a static function with a default implementation to your protocol, then call that static function from the init of conforming types.
protocol TetrisPiece {
static var dataTable: [String] { get }
/// Method to be run when creating a new piece
static func setup()
}
extension TetrisPiece {
static func setup() {
print("Doing common stuff")
}
}
class SquarePiece: TetrisPiece {
static var dataTable: [String] = []
init() {
Self.setup()
// Do the custom init here
}
}

What is the more accurate difference between function overriding and function mutating? In swift particularly

Essentially both are used to modify behaviour of a function to our custom needs. But why the necessity arise to have two ways to do the same thing when both are used for same purpose.
I'm assuming, if a function has HEAD which takes parameters and a BODY which has a certain functionality with those parameters
Mutating function is used when we have to modify at the HEAD.
Mutating -> HEAD -> parameters and
Overriding function is used when we have to modify at the BODY
Overriding -> BODY -> functionality
I've searched over the internet..but found no satisfactory explanation anywhere. Please help me understand them better. Please correct me if I'm wrong.
Mutating
Swift structs are immutable objects meaning that you cannot change its properties within its functions. You need to explicitly mention that you agree to make changes to its properties by adding the mutating keyword in the function definition. However this mutating jargon is required only for value types in Swift - structs and enums.
struct MutatingExample {
var number: Int = 0
// Add 'mutating' to resolve the error
func changeNumber(changedNumber: Int) {
self.number = changedNumber // Error: Cannot assign to property: 'self' is immutable
}
}
Here is an useful post that might provide you more insights - What does the Swift 'mutating' keyword mean?
Reference types such as class do just fine and allow you to change the properties within their functions.
Override
Override is a concept used in inheritance. By that we can infer that override is applicable to reference types such as class and value type(struct/enums) are out of question.
As the name implies, we use the keyword to override an existing functionality, typically that of a super class. For example,
class Parent {
func getName() {
print("Parent")
}
}
class Child: Parent {
// Add override to resolve error
func getName() {
print("Child") // Error: Overriding declaration requires an 'override' keyword
}
}
Useful link: https://www.hackingwithswift.com/sixty/8/3/overriding-methods

Get the class or struct that conforms to a protocol for use in function using Generics

My question if you have an Array of objects that conforms to a protocol. I want to iterate over the array calling a method on each member in the array. However the method I want to call is static and uses generics. I need to get the class of the element in the array to do this. how do you get the class of that object? Is it possible?
I am writing a library of generic functions in Swift.
I have a protocol called DBAble which has as function:
static func get<T: DBable >(id:Int) -> T?
I have an array of objects that conform to DBAble:
let objs:[DBAble] = []
I want to iterate over the array and call:
for obj in objs {
obj.get(id: anInt)
}
however I am getting this message:
Static member 'get' cannot be used on instance of type 'DBable.Protocol'
Is there a way of finding the class (or type of struct) of the object that conforms to the protocol? I understand that I can do:
if obj is User {
}
however this is not the solution I am looking for.
The problem with the application approach it that the type T in the bellow method
static func get<T: DBable >(id:Int) -> T?
has to be known at compile time, whereas the the dynamicType will give you the type at run time.
For anyone else considering this question the answer is no it is not possible to find the type for use in a generic function at runtime. As explained in the comments by #hamish
"element.dynamicType is the actual type of a given element in your array. Your get(_:) method has a generic parameter T that must be known at compile time"

Is it possible to have an array of instances which take a generic parameter without knowing (or caring) what the parameter is?

Consider the following test case, which contains a 'factory' class which is able to call a closure it contains, providing a new instance of some 'defaultable' type:
protocol Defaultable {
init()
}
extension Int: Defaultable { }
extension Double: Defaultable { }
extension String: Defaultable { }
class Factory<T : Defaultable> {
let resultHandler: (T) -> ()
init(resultHandler: (T) -> ()) {
self.resultHandler = resultHandler
}
func callResultHandler() {
resultHandler(T.init())
}
}
Now, this works well when I use it on its own, where I can keep track of the generic type:
// Create Int factory variant...
let integerFactory = Factory(resultHandler: { (i: Int) in print("The default integer is \(i)") })
// Call factory variant...
integerFactory.callResultHandler()
Unfortunately, it doesn't work so well if I want to use factories in a way where I can't keep track of the generic type:
// Create a queue of factories of some unknown generic type...
var factoryQueue = [Factory]()
// Add factories to the queue...
factoryQueue.append(integerFactory)
factoryQueue.append(doubleFactory)
factoryQueue.append(stringFactory)
// Call the handler for each factory...
for factory in factoryQueue {
factory.callResultHandler()
}
I understand the error I get (Generic parameter 'T' could not be inferred), but I don't understand why I can't do this, because when I interact with the array, I don't need to know what the generic parameter is (I don't interact with any of the generic things in the Factory instance). Is there any way I can achieve the above?
Note that the above is a simplified example of what I'm trying to do; in actuality I'm designing a download manager where it can infer what type of file I want (JSON, image, etc.) using generics; the protocol actually contains an init(data:) throws initialiser instead. I want to be able to add the download objects to a queue, but I can't think of any way of adding them to a queue because of the generic nature of the download objects.
The problem is that Swift's strict type safety means you cannot mix two instances of the same class with different generic parameters. They are effectively seen as completely different types.
However in your case, all you're doing is passing a closure to a Factory instance that takes a T input, and then invoking it at any given time with T.init(). Therefore, you can create a closed system in order to contain the type of T, meaning that you don't actually need your generic parameter to be at the scope of your class. You can instead restrict it to just the scope of the initialiser.
You can do this by defining your resultHandler as a Void->Void closure, and create it by wrapping the passed closure in the initialiser with another closure – and then passing in T.init() into the closure provided (ensuring a new instance is created on each invocation).
Now whenever you call your resultHandler, it will create a new instance of the type you define in the closure that you pass in – and pass that instance to the closure.
This doesn't break Swift's type safety rules, as the result of T.init() is still known due to the explicit typing in the closure you pass. This new instance is then being passed into your closure that has a matching input type. Also, because you never pass the result of T.init() to the outside world, you never have to expose the type in your Factory class definition.
As your Factory class itself no longer has a generic parameter, you can mix different instances of it together freely.
For example:
class Factory {
let resultHandler: () -> ()
init<T:Defaultable>(resultHandler: (T) -> ()) {
self.resultHandler = {
resultHandler(T.init())
}
}
func callResultHandler() {
resultHandler()
}
}
// Create Int factory variant...
let integerFactory = Factory(resultHandler: { (i: Int) in debugPrint(i) })
// Create String factory variant...
let stringFactory = Factory(resultHandler: { (i: String) in debugPrint(i) })
// Create a queue of factories of some unknown generic type...
var factoryQueue = [Factory]()
// Add factories to the queue...
factoryQueue.append(integerFactory)
factoryQueue.append(stringFactory)
// Call the handler for each factory...
for factory in factoryQueue {
factory.callResultHandler()
}
// prints:
// 0
// ""
In order to adapt this to take an NSData input, you can simply modify the resultHandler closure & callResultHandler() function to take an NSData input. You then just have to modify the wrapped closure in your initialiser to use your init(data:) throws initialiser, and convert the result to an optional or do your own error handling to deal with the fact that it can throw.
For example:
class Factory {
let resultHandler: (NSData) -> ()
init<T:Defaultable>(resultHandler: (T?) -> ()) {
self.resultHandler = {data in
resultHandler(try? T.init(data:data)) // do custom error handling here if you wish
}
}
func callResultHandler(data:NSData) {
resultHandler(data)
}
}
I recently came back to needing a better answer for this question—as I was performing some refactoring—and thought that it would be really useful to have generic properties of the class, which of course would mean that the class itself would have to be generic as well.
I'm not sure why it didn't occur to me before, but I can simply create a protocol which mirrors the non-generic methods of the class. Using the example I originally had in my question, I could create a FactoryProtocol like so:
protocol FactoryProtocol {
func callResultHandler()
}
Make the class conform to it:
class Factory<T : Defaultable>: FactoryProtocol
And then use the protocol rather than the class when I define my array:
var factoryQueue = [FactoryProtocol]()
This allows me to add any type of specialised Factory to the array and interact with the non-generic methods as I please.
I am afraid this is not possible. The reason for this is that Swift doesn't have first class metatypes. I can imagine all sorts of Monads and Functors being built if this was possible. Unfortunately, this is a limitation. Welcome to Swift.
The golden rule is that in Swift, you cannot nail a type down to a protocol. Swift needs a concrete type.
Check this article out for more details around the subject.

Why is `required` not a valid keyword on class functions in Swift?

It seems that there are a few situations in which a required keyword on Swift class functions would be extremely beneficial, particularly due to the ability of class functions to return Self.
When returning Self from a class func, there are unfortunately two restrictions that make implementing said function very difficult/inhibitive:
You cannot use Self as a type check inside the function implementation, ie:
class Donut {
class func gimmeOne() -> Self {
// Compiler error, 'Self' is only available in a protocol or as the result of a class method
return Donut() as Self
}
}
You cannot return the actual type of the class itself, ie:
class Donut {
class func gimmeOne() -> Self {
// Compiler error, 'Donut' is not convertible to 'Self'
return Donut()
}
}
The reason for these compiler errors is valid. If you have a GlazedDonut subclass that does not override this class function, it is possible that calling GlazedDonut.gimmeOne() will give you back a Donut, which is not a Self.
It seems this situation could be alleviated by allowing classes to specify these functions with required. This would ensure that any subclasses override the method and encur their own round of type checking, making sure that a GlazedDonut returns itself in all cases, eliminating the possibility for a Donut to come back.
Is there a technical, authoritative reason why this has not been added? I'd like to suggest it as an improvement to the Swift team, but want to ensure there isn't an obvious reason why it has been omitted, or cannot be accomplished.
The idea for this question originates here:
https://stackoverflow.com/a/25924224/88111
required is generally only used on initializers, because initializers are not always inherited in Swift. Therefore, to allow you to call an initializer on a variable class (i.e. a value of metaclass type, say Foo.Type), you need to know that that class Foo, and all possible subclasses, have this initializer.
However, methods (both instance methods and class methods) are always inherited. Therefore, required is not necessary.
By the way, your assertion that "You cannot return the actual type of the class itself" is not true. (In fact, the error "'Self' is only available in a protocol or as the result of a class method" itself says you can return the type of the class itself.) Similar to in Objective-C, you can do:
class Donut {
required init() { }
class func gimmeOne() -> Self {
return self()
}
}
You could use a protocol to make the method 'required'
protocol IDonut{
class func gimmeOne()->Donut;
}
class Donut:IDonut {
class func gimmeOne() -> Donut {
return Donut();
}
}
class GlazedDonut: Donut, IDonut{
override class func gimmeOne()->Donut{
return GlazedDonut();
}
}