Protocol only implemented by struct or immutable
Protocols shouldn't be used this way. Protocols is to define behaviour, not the exact shape of object.
I assume by restricting protocol to structs you want to achieve immutability of it's implementers. If so we can design protocol with getters only
protocol Foo {
var foo: string { get }
}
This way Foo
is immutable and it's can't be changed from anywhere no matter if it's struct
or class
.
Then, we can inherit FooMutable
from Foo
and add mutators there
protocol FooMutable: Foo {
var foo: string { get set }
}
Finally class A
is the only place where we can mutate Foo
:
class A {
private var fooValue: FooMutable = FooImpl()
var foo: Foo { get { return fooValue } }
func mutateFoo() {
fooValue.foo = "bar"
}
}
class FooImpl: FooMutable {
var foo = "foo"
}
Why Swift protocol conforming values are treated as Value types by default?
Your protocol SampleProtocol
could be adopted by a class
or a struct
. Swift is using the behavior of the value type which is the more restrictive type until you tell it that the protocol will only be used by a class
reference type.
Add conformance to AnyObject
to your protocol to get reference type behavior:
protocol SampleProtocol: AnyObject {
var message: String? { get set }
}
See The Swift 5.1 Programming Guide - Class-Only Protocols for more details.
The guide notes:
Use a class-only protocol when the behavior defined by that protocol’s
requirements assumes or requires that a conforming type has reference
semantics rather than value semantics.
Historical note: Using class
keyword:
Prior to Swift 4.0, this was written using the class
keyword:
protocol SampleProtocol: class {
var message: String? { get set }
}
This still works for the time being, but it is currently just a type alias for AnyObject
and will likely be removed in a later version of Swift.
Swift protocol to only implemented by specific classes
You could add a required method that you only extend for the appropriate classes.
for example:
protocol PeopleProtocol
{
var conformsToPeopleProtocol:Bool { get }
}
extension PeopleProtocol where Self:People
{
var conformsToPeopleProtocol:Bool {return true}
}
class People
{}
class Neighbours:People
{}
extension Neighbours:PeopleProtocol // this works
{}
class Doctors:People,PeopleProtocol // this also works
{}
class Dogs:PeopleProtocol // this will not compile
{}
This could easily be circumvented by a programmer who would want to, but at least it will let the compiler warn you if you try to apply the protocol to other classes.
Can you restrict a Swift generic constraint to a set of known types?
Can I "or" the constraints somehow?
No, you cannot. However, this will accomplish the same objective.
Define a new protocol:
protocol MetadataRawValue { }
Add your conforming types:
extension Double: MetadataRawValue { }
extension Bool: MetadataRawValue { }
extension String: MetadataRawValue { }
And finally:
struct MetadataValue<T> where T: MetadataRawValue {
...
}
Is a protocol either a reference or value type in Swift?
I don't think this should increase the reference count:
var transferServiceScanner: TransferServiceScanner
increases the reference count to one, since all references are strong if they are not declared weak or sth else.
Storing the delegate variable as weak
makes sure strong references do not go both ways and so ARC can deinit them.
I'm trying to figure out if a class were to simply conform to a protocol, does this create a reference?
A class is always a reference-type, whether you refer to it through a protocol or directly. So assigning a protocol with a reference-type(class) behind it does not copy the class-object, but you rather give out another reference to the object and increases the reference-count which ARC looks at.
With
protocol TransferServiceScannerDelegateProtocol: NSObjectProtocol {
you are making sure, that only a class can implement the protocol, that is why you can declare weak var delegate: TransferServiceScannerDelegateProtocol
, because only classes can implement NSObjectProtocol
with NSObject
& co.
Without declaring a protocol class-only, either a struct or a class, both can implement the protocol. But only if you restrict the protocol to class-only can you use the protocol as if it were a class, using things like weak
with it.
Related Topics
Skaction Completion Handlers; Usage in Swift
How to Implement iOServicematchingcallback in Swift
Why Does Int(Float(Int.Max)) Give Me an Error
Get Signed Integer from Swift String of Binary
How to Animate Bordercolor Change in Swift
In Swift,There's No Way to Get the Returned Function's Argument Names
Extending View with Extra Function Without Using Anyview
Difference Between Type Method and Type Instance Method, etc
Get "Does Not Implement Methodsignatureforselector" When Try to Store Array in Nsuserdefaults,Swift
Continuously Train Coreml Model After Shipping
Mutating Function Inside Class
How to Generate Random Numbers Without Repetition in Swift
Rotating a Cgpoint Around Another Cgpoint
Multi-Face Detection in Realitykit
Why Is It Legal to Mutate an Actor's Nonsendable Property
Using Delegates on Generic Protocol