Swift 4 error on Release configuration - swift

If you run this code on Xcode 9.1 using the Optimization level Fast, whole Module Optimization, it crashes. If the Optimization level is set to None, everything goes fine.
Does anyone have an idea of the issue?
protocol FooProtocol {
func foo()
}
class FooProtocolImplementation : NSObject, FooProtocol {
func foo() {}
}
var set: Set<AnyHashable> = []
_ = set.insert(FooProtocolImplementation())
let array = set.flatMap { $0 as? FooProtocol } // filtering out nils
_ = array[0] // # error (EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

Apple reported it as a bug and fixed it in Xcode 9.3

Related

Swift generic sequence observable ambiguity

I've got following code
protocol NamedOption {
var optionTitle: String { get }
}
struct DebugOption: NamedOption {
let optionTitle: String
let debugViewControllerType = UIViewController.self
}
func testFunk<T: Sequence>(d: Observable<T>) where T.Element == NamedOption {
}
func bindFullResultsRx() {
let dd: Observable<[DebugOption]> = self.dataModel.debugOptions // this is defined and properly assigned earlier
testFunk(d: dd)
}
and at the line where I call testFunk Xcode gives me following error:
Expression type '()' is ambiguous without more context
I have no idea why this is happening :( So far I was able to make it working by changing constraints on testFunk into this:
func funk<T: NamedOption>(d: Observable<[T]>) {
}
which seems to me more restrictive then version at the top. Does any one knows how to make it working with T: Sequence ?
Xcode version is 9.4, Swift version is 4.1.
After some digging and help from work colleagues I was able to make it working by simply changing == into : so it looks like this
func testFunk<T: Sequence>(d: Observable<T>) where T.Element: NamedOption {
}
It's just a matter of swift syntax
https://docs.swift.org/swift-book/ReferenceManual/GenericParametersAndArguments.html
conformance-requirement → type-identifier : protocol-composition-type
OO and generics don't play too well together. In order to do what you want, you have to manually cast up as in:
testFunk(d: dd.map { $0.map { $0 as NamedOption } })

Command failed due to signal: Segmentation fault: 11 while emitting IR SIL function

I want to add closure properties in the extension of UITextView so I define a closure using typealias:
typealias TextViewHeightDidChangedClosure = (_ currentTextViewHeight:CGFloat)->Void
extension UITextView{
func setTextViewHeightDidChanged(textViewHeightDidChanged:TextViewHeightDidChangedBlock){
objc_setAssociatedObject(self, &TextViewHeightDidChangedBlockKey, textViewHeightDidChanged, objc_AssociationPolicy.OBJC_ASSOCIATION_COPY_NONATOMIC)
}
func textViewHeightDidChanged()->TextViewHeightDidChangedBlock?{
let textChanged : ((CGFloat)->Void) = objc_getAssociatedObject(self, &TextViewHeightDidChangedBlockKey) as! TextViewHeightDidChangedBlock
return textChanged
}
}
But it tells me an error that says:
Command failed due to signal: Segmentation fault: 11.
Here is an image of the error
Can anyone tell me why and give me an deep meaningful explanation, thank you very much!
You can also have this error if you declare a Bool! property in a class and you try to make a ternary condition with this property:
var isSomething: Bool!
func myFunc() {
let value = isSomething ? "something" : "not"
}
Just add the ! on your property
var isSomething: Bool!
func myFunc() {
let value = isSomething! ? "something" : "not"
}
Generally, crashing with SegFault 11 is a bug of compiler and you'd better send a bug report.
And most such bugs can be worked around with fixing your code properly.
The most significantly bad thing in your code is that usual closures in Swift (#convention(swift) -- usually omitted) cannot be passed to Any which represents id of Objective-C. Use #convention(block) which is stated as id-compatible in the Swift book (this part):
typealias TextViewHeightDidChangedBlock = #convention(block) (_ currentTextViewHeight:CGFloat)->Void
You may have tried this, but in this case, just putting #convention(block) does not solve the issue.
It seems another trick is needed to make your code work, explicitly cast to AnyObject:
extension UITextView{
func setTextViewHeightDidChanged(textViewHeightDidChanged: #escaping TextViewHeightDidChangedBlock){
objc_setAssociatedObject(self, &TextViewHeightDidChangedBlockKey, textViewHeightDidChanged as! AnyObject, objc_AssociationPolicy.OBJC_ASSOCIATION_COPY_NONATOMIC)
}
func textViewHeightDidChanged()->TextViewHeightDidChangedBlock?{
let textChanged : ((CGFloat)->Void) = objc_getAssociatedObject(self, &TextViewHeightDidChangedBlockKey) as! TextViewHeightDidChangedBlock
return textChanged
}
}
So, this seems to be a flaw of id-as-Any. Any which represents id should accept id-compatible closure.
I'm not sure Apple would fix this bug soon, but anyway, as far as I tested, my code above worked as expected.
For me it was because I was declaring protocols for two extensions on a generic class and implementing them in the class declaration. I am using xCode 9 swift 4
I faced the similar issue in Xcode 9.3, I opened the given swift class as mentioned in error image(mine was differ), went to method(mention in error) there was code like below
class func makeViewCircular(view: AnyObject) {
let viewCircle = view
viewCircle.layer.cornerRadius = view.frame.size.width/2
viewCircle.layer.borderColor = UIColor.clear.cgColor
viewCircle.layer.borderWidth = 1.0
}
So, I edit the code to like below. Fixed the problem. The problem was with the AnyObject type. I typecast AnyObject to UIView.
class func makeViewCircular(view: AnyObject) {
if let viewCircle = view as? UIView{
viewCircle.layer.cornerRadius = view.frame.size.width/2
viewCircle.layer.borderColor = UIColor.clear.cgColor
viewCircle.layer.borderWidth = 1.0
}
}
In my case, the swift class I am referring in Objective-C is missing #objc. I was using #class in my .h file and referring the swift class in header file. Might help someone as the error doesn't gives any clue about this.

Crash on swift class init when using inline initializers

I'm developing an application and I encountered a crash that I can't explain.
The library is fairly complex so I prepared a minimum example
struct Info {
static let test = 1
}
class SuperCls<A> {}
class Cls<A>: SuperCls<A> {
let v: Info.Type = Info.self
}
let v = Cls<Int>()
This code crashes when I alloc the class, in the very last line, with the following error
file:///play.playground/: error: Playground execution aborted: error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0x4403).
I also tried this in an xcode project and the error is pretty much the same
I found a way to make this code works
struct Info {
static let test = 1
}
class SuperCls<A> {}
class Cls<A>: SuperCls<A> {
var v: Info.Type?
override init() {
v = Info.self
super.init()
}
}
let v = Cls<Int>()
Can someone tell me why this crash occurs?
Thanks!
UPDATE
I also discovered that this works
struct Info {
let test = 1
}
class SuperCls<A> {}
class Cls<A>: SuperCls<A> {
let v = Info()
}
let v = Cls<Int>()
The problem seems to be related to the fact that I'm using Info as a type and accessing static information
Alright, it seems that it is a bug in Xcode beta 5
Thanks for the help

Confused by Ambiguous Reference Member Reference error in Swift

Given this workspace example:
import Foundation
import CoreBluetooth
class Something: NSObject, CBPeripheralDelegate {
var peripheral:CBPeripheral!
func peripheral(peripheral: CBPeripheral, didUpdateValueForDescriptor descriptor: CBDescriptor, error: NSError?) {
}
func foobar() {
self.peripheral.writeValue([], forDescriptor: 0) // I use a real value instead of 0 in real code
}
}
I get errors that look like:
Playground execution failed: Playground2.playground:6:3: error: ambiguous reference to member 'peripheral'
self.peripheral.writeValue([], forDescriptor: 0)
^~~~
Playground2.playground:5:6: note: found this candidate
var peripheral:CBPeripheral!
^
Playground2.playground:1:7: note: found this candidate
func peripheral(peripheral: CBPeripheral, didUpdateValueForDescriptor descriptor: CBDescriptor, error: NSError?) {
So, it can't seem to decide if my self.peripheral code is a reference to my variable named peripheral or one of the delegate functions I've chosen to implement? I guess I could rename my peripheral variable to be something else...
But what surprises me is that if I construct what seems like a similar example, it has no issues disambiguating:
import Foundation
extension Int {
func frobnicate() { }
func barf() { }
}
class YakAttack: NSObject {
var something:Int!
func something(something:Int, else:Int) {
}
func foobar() {
self.something.frobnicate()
}
}
The foobar() function should have the same issue with the self.something reference, but it has no such problem. What's the difference?
(I am using XCode 7.3 Beta 5, which has the latest Swift version in it)
My best guess is it's a message passing confusion due to dealing with Objective-C protocols/datatypes. I'm not really qualified to analyze the specific, but thus far I've learned there are still some weird bugs like this that come up when dealing with both languges.
I'm guessing this will be fixed down the road, but for now you'll probably just have the change the variable name.

Swift 1.2 redeclares Objective-C method

I just updated from swift 1.1 to swift 1.2 and get compiler Error:
Method 'setVacation' redeclares Objective-C method 'setVacation:'
Here some code:
var vacation : Vacation?
func setVacation(_vacation : Vacation)
{...}
But I need call setVacation
Is any suggestions how fix this?
This is cause by the change stated in Xcode 6.3beta release notes:
Swift now detects discrepancies between overloading and overriding in
the Swift type system and the effective behavior seen via the
Objective-C runtime. (18391046, 18383574) For example, the following
conflict between the Objective-C setter for “property” in a class and
the method “setProperty” in its extension is now diagnosed:
class A : NSObject {
var property: String = "Hello" // note: Objective-C method 'setProperty:’
// previously declared by setter for
// 'property’ here
}
extension A {
func setProperty(str: String) { } // error: method ‘setProperty’
// redeclares Objective-C method
//'setProperty:’
}
To fix this you need to make all you method signatures unique (as Objective-C does not provide method overload)
Or don't inherit from NSObject if you need Swift only class.
Cappy: For the Standford problem I used simply this, because it looks like the Xcode Beta simply says that the operation: (Double, Double) -> Double is the same as operation: Double -> Double, I don't know if it is a bug or not...
But the code below works, but is NOT clean :(
func performOperation(r:String? = "2", operation: (Double, Double) -> Double) {
if operandStack.count >= 2 {
displayValue = operation(operandStack.removeLast(), operandStack.removeLast())
enter()
}
}
func performOperation(operation: Double -> Double) {
if operandStack.count >= 1 {
displayValue = operation(operandStack.removeLast())
enter()
}
}
As noted by #Kirsteins, Swift now detects conflicting symbols between Swift and Obj-C, and swift symbols that would cause Obj-C grief. In addition to the answer given, you can avoid this in general by specifying a required label for the additional types, thus changing the call signature:
import Foundation
extension NSObject {
func foo(d:Double, i:Int) { println("\(d), \(i)") }
func foo(withInt d:Int, i:Int) { println("\(d), \(i)") }
}
let no = NSObject()
no.foo(withInt:1, i: 2)
Beyond that though, and to answer your immediate question, you are trying to apply Obj-C idioms to Swift. What you really want, is to either implement didSet (most likely), or possibly set:
class WhatIDidLastSummer {
var vacation:Bool = false {
didSet {
// do something
}
}
var staycation:Bool {
get { return true }
set {
// do something
}
}
}