How to update NSResponder selector in swift 2.2 - swift

I am implementing a NSControlTextEditingDelegate protocol and I don't know which class/protocol i should match with e.g. commandSelector. #selector(WhichClass.moveUp(_:)) so that the equality will pass.
Currently everything is ok with swift 2.1:
func control(control: NSControl, textView: NSTextView, doCommandBySelector commandSelector: Selector) -> Bool {
var goUp = false
var goDown = false
if (commandSelector == Selector("moveUp:") ||
commandSelector == Selector("moveBackward:") ||
commandSelector == Selector("moveUpAndModifySelection:") ||
commandSelector == Selector("moveParagraphBackwardAndModifySelection:")
)
{
goUp = true
}
if (commandSelector == Selector("moveDown:") ||
commandSelector == Selector("moveForward:") ||
commandSelector == Selector("moveDownAndModifySelection:") ||
commandSelector == Selector("moveParagraphForwardAndModifySelection:")
) {
goDown = true
}
//...
}

Try this:
if (commandSelector == #selector(NSResponder.moveUp) ||
You can write it as the following if you prefer:
if (commandSelector == #selector(NSResponder.moveUp(_:)) ||
In fact, generated Selector instance from #selector does not contain the class info. So, you just find any class defining the same method with the same signature.
And if you cannot find any class, you can define it in your own protocol and use the protocol name.
#objc protocol MyProtocol {
func moveUp(_:AnyObject)
//...
}
And use it in #selector:
if (commandSelector == #selector(MyProtocol.moveUp(_:)) ||
The latter should be the last way, but it actually works.

Related

Recursive Binary Tree in swift

This algorithm correctly searches a tree and returns true if the searchValue is in the tree, I understand the base case, but I'm a little lost on the else statement, I'm not understanding what the || does in this scenario, is it returning both of those or just one in certain cases?
func search(node: Node?, searchValue: Int) -> Bool {
if(node == nil){
return false
}
if(node?.value == searchValue){
return true
} else {
return search(node: node?.leftChild, searchValue: searchValue) || search(node: node?.rightChild, searchValue: searchValue)
}
}

Overloading == operator calls parent function for !=

I overloaded the == operator on a class. Then a child class also overloads the == operator. My understanding is that both == and != are supposed to call the same == function. However, when running tests, == calls the function on the child class, yet != calls the function on the parent class. This is bizarre. I would expect the same behavior for both == and !=.
class Description: Equatable {
var id : Int = IdFactory.id()
static func == (lhs: Description, rhs: Description) -> Bool {
assertionFailure("Child Description must override == method.")
return false
}
}
class LineDescription : Description {
var track = 0
static func == (lhs: LineDescription, rhs: LineDescription) -> Bool {
if lhs.track != rhs.track { return false }
return true
}
}
import XCTest
class LineDescriptionTest: XCTestCase {
func testEquality(){
let ld = LineDescription()
ld.track = 9
let ld2 = LineDescription()
ld2.track = 9
XCTAssert(ld == ld2) //<--Calls child == function
ld2.track = 1
XCTAssert(ld != ld2) //<--Calls parent != function
}
}

A set is not equal but an array from this set is equal?

I work with unit-tests and encounter this problem:
I have some classes and each have their own isEqual() method. At some point I came to a situation where an unit-test sometimes fails and sometimes succeeds.
I check the equality of two objects that contain a set of objects. Here the the problem arises. Sometimes the test "obj1.mySet == obj2.mySet" fails - sometimes not. I test this with only one object in each set (mySet). The test for the equality of this objects (in mySet) itself succeeds.
I tried some hours to find a mistake in my code, but couldn't find any. Now I have a workaround that helps to pass the test, but I do not understand, what's going on. I have a method within the test-objects, that returns the objects of the set as an (ordered) array. When I test the equality of this arrays, the test always succeeds.
Do someone know, what’s going on?
Update:
In my BaseClass
func hash(into hasher: inout Hasher) { hasher.combine(firebaseID) }
static func == (lhs: FirebaseObject, rhs: FirebaseObject) -> Bool { return lhs.isEqual(to: rhs) }
func isEqual(to object: Any?) -> Bool {
guard object != nil && object is FirebaseObject else { return false }
let value = object as! FirebaseObject
return firebaseID == value.firebaseID && name == value.name
}
In the SubClass
override func isEqual(to object: Any?) -> Bool {
guard object != nil && object! is MealPlanned else { return false }
let obj = object as! MealPlanned
var result = ""
if !super.isEqual(to:obj) { result.append("fbObject ") }
if portions != obj.portions { result.append("portions ") }
if imgID != obj.imgID { result.append("imgID ") }
if meal != obj.meal { result.append("meal ") }
if date != obj.date { result.append("date ") }
if portionsInBaseMeal != obj.portionsInBaseMeal {result.append("portionsInBaseMeal ") }
if getIngrediencesInMeals() != obj.getIngrediencesInMeals() { result.append("ingrediencesInMeals ") }
if result.count > 0 {
if (showsDifference) { print("difference in MealPlanned <\(obj.name ?? "Fehler")>: \(result)") }
return false
}
return true
}
I did it this way, to find and print the problem.
This version succeeds.
if getIngrediencesInMeals() != obj.getIngrediencesInMeals() { result.append("ingrediencesInMeals ")
getIngrediencesInMeals() returns the set as an ordered array.
In this way the test sometimes succeeds sometimes fails:
if ingrediences != ingrediences { result.append("ingrediencesInMeals ")
This returns the ordered array:
func getIngrediencesInMeals() -> [IngredienceInMeals] { return ingrediences.sorted{ $0.position < $1.position } }
in IngredienceInMeals
override func isEqual(to object: Any?) -> Bool {
guard object != nil && object! is IngredienceInMeals else { return false }
let obj = object as! IngredienceInMeals
var result = ""
if !super.isEqual(to:obj) { result.append("fbObject ")}
if unit != obj.unit { result.append("unit ")}
if quantity != obj.quantity { result.append("quantity ")}
if ingredience != obj.ingredience { result.append("ingredience ")}
if position != obj.position { result.append("position ")}
if result.count > 0 {
if (showsDifference) { print("difference in IngredienceInMeal <\(obj.name ?? "Fehler")>: \(result)") }
return false
}
return true
}
if you want to compare two objects use Equatable protocol method in your object class
example of compare two objects
class ItemModel : Equatable {
var TypeOfOffer : String?
var TypeOfSelling : String?
var Address : String?
var NumberOfRoom : String?
var Price : String?
var Image : String?
var ID : String?
var itemId : String?
init(TypeOfOffer : String? , TypeOfSelling : String?, Address : String?, NumberOfRoom : String? , Price : String?, Image : String?, ID : String?, itemId : String? )
{
self.TypeOfOffer = TypeOfOffer
self.TypeOfSelling = TypeOfSelling
self.Address = Address
self.NumberOfRoom = NumberOfRoom
self.Price = Price
self.Image = Image
self.ID = ID
self.itemId = itemId
}
static func == (lhs: ItemModel, rhs: ItemModel) -> Bool {
var isIt = true
isIt = (lhs.TypeOfOffer == "" || lhs.TypeOfOffer == rhs.TypeOfOffer)
&& (lhs.TypeOfSelling == "" || lhs.TypeOfSelling == rhs.TypeOfSelling)
&& (lhs.Address == "" || lhs.Address == rhs.Address)
&& (lhs.NumberOfRoom == "" || lhs.NumberOfRoom == rhs.NumberOfRoom)
&& (lhs.Price == "" || lhs.Price == rhs.Price)
return isIt
}
}
Compare two instances of an object in Swift!

How to check if nested optional is nil in generic class?

I have simple class:
class Values<T> {
let new: T
let old: T?
init(new: T, old: T? = nil) {
self.new = new
self.old = old
}
func changed<TProp: AnyObject>(_ getter: (T) -> TProp) -> Bool {
return old == nil || !(getter(old!) === getter(new))
}
func changed<TProp: Equatable>(_ getter: (T) -> TProp) -> Bool {
return old == nil || !(getter(old!) == getter(new))
}
}
When using it as Values<ChartViewModelData?> where ChartViewModelData is a class i got problems when old is nested optional - it is both nil and not equal to nil:
So changing function like this doesn't help:
return old == nil || old! == nil || !(getter(old!) === getter(new))
nil shouldn't be passed to the getter function, and i don't know how to achieve it.
Reproduce:
class PropClass {}
class TestClass {
var someProp = PropClass()
}
let values = Values<TestClass?>(new: TestClass(), old: Optional<Optional<TestClass>>(nil))
values.changed({ $0!.someProp }) /* Fatal error: Unexpectedly found nil while unwrapping an Optional value */
values.changed({ $0?.someProp }) /* error: cannot convert value of type '(TestClass?) -> PropClass?' to expected argument type '(TestClass?) -> _' */
Second error appears because it can't use === on two Optional.
Just spent couple of hours looking for a solution to the similar problem and I think I have finally found one. To check if nested value is nil for generic type you can use this:
if (newValue as AnyObject) is NSNull {
//value is nil
}

Defining `Comparable` for optional types in Swift 1.2

import SwiftyJSON
public typealias FeedItem = JSON
extension FeedItem {
var id: Int { get { return self["id"].intValue } }
}
public func <(lhs: FeedItem, rhs: FeedItem) -> Bool {
return lhs.id < rhs.id
}
public func ==(lhs: FeedItem, rhs: FeedItem) -> Bool {
return lhs.id == rhs.id
}
extension FeedItem:Comparable {}
extension Optional : Comparable {}
public func < <T>(l:T?, r:T?) -> Bool {
if let a=l,b=r {
return a < b
} else if (l==nil) && (r != nil) { return true }
else { return false }
}
public func == <T>(l:T?, r:T?) -> Bool {
if let a=l, b=r {
return a==b
} else {
return false
}
}
First, it should read extension Optional<T where T:Comparable>: Comparable but swift 1.2 does not allow that. Anyway I can express the constraint more explicitly rather than expecting the reader to realize the fact by noticing return a < b and return a==b ?
Second (and apparently more important): the code above works when I use < and > but minElement and maxElement both return nil when a nil is present in their input no matter what and min and max fall into infinite recursion:
let items: [FeedItem?] = [ nil, .Some(JSON(["id":2])), .Some(JSON(["id":1])) ]
println(items[0]?.id) // nil
println(items[1]?.id) // Optional(2)
println(items[2]?.id) // Optional(1)
println(items[0] < items[1]) // true
println(items[1] < items[2]) // false
println(items[2] < items[1]) // true
println(minElement(items)) // nil
println(maxElement(items)) // nil
println( min(items[0],items[2]) ) // nil
println( min(items[2],items[1]) ) // crashes due to infinite recursion
I'm no debug (or swift) expert but from what I can gather in XCode I believe the
if let a=l,b=r {
return a < b
}
part somehow misses the point that a and b are not Optionals but FeedItems. I expect the a < b should call the < operator on FeedItem and not the one on Optional but apparently this is exactly what happens; i.e. a < b resolves to the same function it is called from (that is, the < for Optionals) and thus a recursion happens. I might be wrong though.
Insights ?