Weird issue during migration from Swift 2 to Swift 3: Initializer has different argument names from those required by protocol
In Swift 2 we used to have NSData with the initializer init(bytes:length:). Since Apple has done a lot of renaming in Swift 3, NSData is called Data and the initializer is called init(bytes:count:) now.
So everything you need to do is to update your KeyType protocol:
public protocol KeyType {
init(bytes: UnsafeRawPointer, count: Int) // change "length" to "count"
func withSlice(_ f: (Slice) -> ())
func asData() -> Data
}
How to create a generic function in Swift that will reject the given parameter unless it is an Optional?
You might want to give this protocol a better name, but I don't foresee any problems with it as-is, unless you're making your own ExpressibleByNilLiteral
types that don't wrap.
protocol ExpressibleByNilLiteral: Swift.ExpressibleByNilLiteral {
associatedtype Wrapped
}
extension Optional: ExpressibleByNilLiteral { }
func onlyCallableByAnOptional<Optional: ExpressibleByNilLiteral>(_ optional: Optional) -> Optional.Wrapped? {
optional as? Optional.Wrapped
}
Recommendation: use an initializer. (Downside is the argument label being necessary to disambiguate, but I personally like the explicitness because of how weird this case is. i.e. Swift makes it easy to enforce that something is not optional, but not vice versa.)
extension Optional: ExpressibleByNilLiteral {
init<Optional: ExpressibleByNilLiteral>(optional: Optional) where Optional.Wrapped == Wrapped {
self = optional as? Wrapped
}
}
+
if let v = Optional(optional: i) { // ERROR, as was desired.
print("integer \(v)")
}
if let v = Optional(optional: oi) { // OK, as expected.
print("optional integer \(v)")
}
Swift: Self.init called multiple times in initializer
I suspect this is a bad diagnostic (i.e the wrong error message). It would be very helpful if you had a full example we could experiment with, but this line doesn't make sense (and I suspect is the underlying problem):
super.init(document: self, gravlNode: node)
You can't pass self
to super.init
. You're not initialized yet (you're not initialized until you've called super.init
). For example, consider the following simplified code:
class S {
init(document: AnyObject) {}
}
class C: S {
public init() {
super.init(document: self)
}
}
This leads to error: 'self' used before super.init call
which I believe is the correct error.
EDIT: I believe Hamish has definitely uncovered a compiler bug. You can exploit it this way in Xcode 8.3.1 (haven't tested on 8.3.2 yet):
class S {
var x: Int
init(document: S) {
self.x = document.x
}
}
class C: S {
public init() {
super.init(document: self)
}
}
let c = C() // malloc: *** error for object 0x600000031244: Invalid pointer dequeued from free list
NSDate code not migrating to Swift 3.0
You can easily remove the convenience
from the init method.
extension Date {
init(posixTime: Double) {
self.init(timeIntervalSince1970: Double(posixTime) / 1000.0)
}
}
Seems like the migration tool has incorrectly convert the self
instance to NSDate in your previous code.
Weird behaviour on Swift protocol methods
As we know from Swift documentation for functions, foo
and bar
are external names for aString
parameter. So technically he have exactly the same function with just different names of parameters that is completely legal in Objective-C:
id<MyProtocol> myVar;
[myVar myProtocolWithBar:@""];
[myVar myProtocolWithFoo:@""];
I think it is a bug in Swift compiler! File a report: http://bugreport.apple.com
Related Topics
How to Bend a Rectangle in Sprite Kit
Animate Line Under One Button to Another
What Is The Intended Use of Optional Variable/Constant in Swift
Why Do I Keep Getting The Error "No Such Module 'Realmswift'"
Midiclientcreate Does Not Work for 32 Bit Processors in Swift
Display Array in a Label in Swift
How to Count Number of Sprites Swift
Using UIscrollview Correctly in Swiftui
Navigationview Inside a Tabview Swift UI
Unexpectedly Found Nil While Unwrapping an Optional Value with Avaudioplayer
Calling Closure Inside Closure
How to Keep Nsmenuitem Selected in a Nspopover with Nsmenu
Swift: Right/Left Click on Nsstatusbar
Functional Programming Way of Doing Array Conversion
Swift, Detect Ibeacons on The Background and Send Notifications When in Range