Swift 3, is the “self” in the metatype question really correct?

I have an extension to go to the view controller chain (even in the form of containers, which is very convenient)

public extension UIViewController // go up to a certain class { public func above<T>(_ : T.Type)->(T) { var p:UIResponder = self repeat { p = p.next! } while !(p is T) return p as! T } } 

(Also, NB, Swift3 needs a “!” On p.next: unfortunately, I don’t know exactly why.)

So, let's say you have a General view controller class, you can

 self.above(General).clickedHamburgerMenuButton() 

and he will find the first "General" above you. Everything is fine, but with Swift 3 you will get this warning .......

Missing '.self' for reference to metatype of type 'General'

It seems that this

 self.above(General.self).clickedHamburgerMenuButton() 

1) It seems ... dangerous ... to change General to General.self - is it really safe and means the same as General in Swift <3?

2) in extension

  public func above<T>(_ : T.Type)->(T) 

why is this a metatype? “I did something wrong” and asked for a meta tag instead of type?

2) What the hell is this "metatype"? (I cannot really find it explained as such anywhere.) That is, what can be “general”, perhaps differently than “the class itself”. (Not an instance or a static instance or something else ...)

+3
generics swift3 metatype
source share
1 answer

(Also, NB, Swift3 needs a “!” On p.next: unfortunately, I don’t know exactly why.)

Since .next returns an optional parameter, but p is not optional. This will crash if you run out of respondents.

1) It seems ... dangerous ... to change General to General.self - is it actually safe and has the same meaning as General in Swift <3?

I am surprised to have worked in earlier versions of Swift without .self , but yes, .self is required to refer directly to the metatype. Linking to metatypes is somewhat rare in Swift and can lead to unexpected behavior if it is done unintentionally, so it requires an extra piece of syntax to say "yes, I really mean the type."

why is this a metatype? “I did something wrong” and asked for a metatep, not just a type?

You did it right.

2) What the hell is this "metatype"?

Type of type. An example of a metatype is a type. Consider:

 func f(x: Int) 

To call this, you pass an instance of Int . Similar:

 func f<T>(x: T.Type) 

To call this, you pass in an instance of the T.Type meta tag, which is a type.


Unrelated, but I would probably change my mind about this code in these lines. Firstly, it’s convenient to be able to consider the chain of respondents as a sequence. Here is one way to do this:

 public extension UIResponder { public func nextResponders() -> AnySequence<UIResponder> { guard let first = next else { return AnySequence([]) } return AnySequence(sequence(first: first, next: { $0.next })) } } 

Then, getting the next responder that matches the type is a cleaner and more understandable IMO (and works in any response chain):

 public extension UIResponder { public func firstResponder<T: UIResponder>(ofType _: T.Type)-> T? { return nextResponders() .flatMap { $0 as? T } .first } } ... self.firstResponder(ofType: General.self)?.clickedHamburgerMenuButton() 
+2
source share

All Articles