Create a weak container in Swift that accepts a native Swift protocol
If you are fine with losing some compile time safety, you can change your Weak
to accept Any
as T
and then store value as AnyObject
:
struct Weak<T: Any>{
weak var value: AnyObject?
public var ref: T? {
get {
return value as? T
}
}
init(value: T) {
self.value = value as AnyObject
}
}
Swift confine protocol to certain types of class only
What you want is a subclass
class SKSceneWithProtocol : SKScene, GameSceneProtocol
but at this point the protocol is essentially pointless, and you may as well just do the code in the subclass instead.
Your other option is to cast the scene to the protocol when you need to use it
if let sceneProtocol = scene as? GameSceneProtocol
{
//do stuff here
}
How to implement a Swift protocol across structs with conflicting property names
The desired feature from explicit interface implementations is that they are statically dispatched, right? If you use Description
on a BusStop
, it will be an optional string, but if you use Description
on a Stop
, it will be a non-optional string.
In Swift, extension members are statically dispatched, so you can make use of this to achieve something similar:
extension Stop where Self == BusStop {
// Since the type of "self" here is BusStop, "Description" refers to the one declared in BusStop
// not this one here, so this won't cause infinite recursion
var Description : String { return self.Description ?? "" }
}
extension Stop where Self == TrainStop {
var Latitude: Double { return self.Latitude ?? 0 }
var Longitude: Double { return self.Longitude ?? 0 }
}
This code shows that this works:
let busStop = BusStop(Code: "ABC", Description: "My Bus Stop", Latitude: 0, Longitude: 0)
print(type(of: busStop.Description)) // Optional<String>
let stop: Stop = busStop
print(type(of: stop.Description)) // String
However, I still don't think this is good Swift code. It is often bad to just directly translate an API from one language to another. If I were you, I would make Longitude
, Latitude
and Description
in Stop
to be all optionals.
Conditionally conform Set to ExpressibleByDictionaryLiteral protocol
You simply need to make the Weighted
protocol public
as well as marking the init public
.
public protocol Weighted: Hashable {
associatedtype D: Hashable
associatedtype W: Hashable
var destination: D { get }
var weight: W { get }
init(destination: D, weight: W)
}
extension Set: ExpressibleByDictionaryLiteral where Element: Weighted {
public init(dictionaryLiteral elements: (Element.D, Element.W)...) {
self.init(elements.map(Element.init))
}
}
Self in protocol
Self.Element
refers to the concrete type that any type implementing GeneratorType
protocol will declare as its Element
typealias.
For example, in this generator of Fibonacci numbers:
struct Fibonacci: GeneratorType {
typealias Element = Int
private var value: Int = 1
private var previous: Int = 0
mutating func next() -> Element? {
let newValue = value + previous
previous = value
value = newValue
return previous
}
}
... you implement GeneratorType
protocol and indicate what will be its Element
typealias (Int
in this case), and that's the type that generator's next()
will be returning (well, actually the optional of that type).
Quite often, though, you would not have to explicitly specify typealiases when implementing parametrised protocols, as Swift is smart enough to infer them for you. E.g. for the Fibonacci numbers generator from the above example the following will also do:
struct Fibonacci: GeneratorType {
private var value: Int = 1
private var previous: Int = 0
mutating func next() -> Int? {
let newValue = value + previous
previous = value
value = newValue
return previous
}
}
... Swift knows from the signature of next()
that it returns Int?
, and that GeneratorType
implementors also must have next()
in their to-do list, and that these methods must return Element?
types. So, Swift just puts 2 and 2 together, and infers that Element?
must be the same thing as Int?
, and therefore Element == Int
.
About this:
public struct IndexingGenerator<Elements : Indexable> : GeneratorType, SequenceType {
public init(_ elements: Elements)
public mutating func next() -> Elements._Element?
}
Here we have four things going on:
- We declare generic type
IndexingGenerator
that takes a parameter-type calledElements
. - This
Elements
type has a constraint that it must implementIndexable
protocol. - The generator that we implement is supposed to return values of the type that is accessible via
Indexable
interface ofElements
, which is known toIndexingGenerator
via dot-syntax asElements._Element
. - Swift infers that
Element
ofIndexingGenerator
is the same thing asElements._Element
.
So, essentially the above delclaration is equivalent to:
public struct IndexingGenerator<Elements : Indexable> : GeneratorType, SequenceType {
public typealias Element = Elements._Element
public init(_ elements: Elements)
public mutating func next() -> Element?
}
Finally, if curious why _Element
and not just Element
like in GeneratorType
, here is what they write in the open-source Swift repository (under swift/stdlib/public/core/Collection.swift):
The declaration of
_Element
and subscript here is a trick used to break a cyclic conformance/deduction that Swift can't handle. We need something other than aCollectionType.Generator.Element
that can be used asIndexingGenerator<T>
'sElement
. Here we arrange for theCollectionType
itself to have anElement
type that's deducible from its subscript. Ideally we'd like to constrain thisElement
to be the same asCollectionType.Generator.Element
, but we have no way of expressing it today.
Swift Function Input Generic Conform To Both Class And Protocol
Not a direct answer to your question but all you need is to add an enumeration to store the kind of measurement to your class, and a computed property to return the corresponding dictionary. No need to use a protocol, protocol composition, class and/or subclass to accomplish what you are trying to do:
struct AMeasurement {
let imperial: Double
let metric: Double
let kind: Kind
enum Kind { case distance, steps }
var units: [String: String] {
switch kind {
case .distance: return ["imperial": "miles", "metric":"kms"]
case .steps: return ["imperial": "steps", "metric":"steps"]
}
}
}
extension AMeasurement {
func printValues() {
print("\(imperial) \(units["imperial"]!) = \(metric) \(units["metric"]!)")
}
}
let distance = AMeasurement(imperial: 30, metric: 48.28, kind: .distance)
let steps = AMeasurement(imperial: 30, metric: 30, kind: .steps)
let types = [distance, steps]
for type in types {
type.printValues()
}
30.0 miles = 48.28 kms
30.0 steps = 30.0 steps
Swinject: Using weak scope is leaking objects
There is no memory leak, it's just a bug in Xcode 8 memory profiling instruments. See discussing at GitHub issues tracker
Related Topics
How to Display an Image by an API Url? Swift
How to Retrieve Audio File from Parse Swift
Store Data in Custom Class Array in Core Data
Swift Format Text Field When User Is Typing
How to Sort an Array of Posts by Their Elements
Prepare for Segue with Array - Xcode 8.0 Swift 3.0
Firebase Datadescription Returns Empty Array
How to Get Video Duration Fro Avasset in Swift
Structuring Data for Chat App in Firebase
Swift Spritekit 3D Touch and Touches Moved
Swift: Casting a Floatingpoint Conforming Value to Double
Nsurl Fail Able Initialiser Initwithstring: Does Not Return Nil on Empty String in Swift
Firestore Security Rules Breaking with Update Rule
Ambiguous Method Overload with Closures in Swift, But Only When Closure Returns a Value
Iterate a Grid of Views Swiftui