这应该可以工作。
class Base {}
class A: Base {}
class B: Base {}
var arrBase: Array<Base> = []
var arrA: Array<A> = []
arrA.append(A())
var arrB: Array<B> = []
arrB.append(B())
arrBase = arrA // no error
arrBase = arrB // no error
你的问题似乎在代码的其他地方。你可以展示一下你的通用结构体OrderedSet的实现吗?看起来你正在尝试做类似于
class Base {}
class A: Base {}
let base = Base()
let a = A()
struct S<T:Base> {
var t: T
}
var s = S(t: base)
let sa = S(t: a)
let sb = S(t: a as Base)
s = sb
...这个有效
protocol P {
func whoAmI()->Void
}
class Base:P {
func whoAmI() {
print("I am Base")
}
}
class A: Base {
override func whoAmI() {
print("I am A")
}
}
let base = Base()
let a = A()
struct S<T: Base> {
var t: Base
}
var s = S(t: base)
let sa = S(t: a)
s = sa
s.t.whoAmI()
.... 伙计们,是内置类型还是不是
import Foundation
// Int and Double conforms to Hashable protocol
var a: Set<Int> = []
var b: Set<Double> = []
a = b // IMPOSSIBLE eventhough Set<T:Hashable> is build-in Swift type
如何处理OrderedSet。
import Foundation
class Exercise: Hashable {
var name: String = ""
var hashValue: Int {
return name.hashValue
}
}
func ==(lhs: Exercise, rhs: Exercise) -> Bool {
return lhs.name == rhs.name
}
class StrengthExercise: Exercise {}
class CardioExercise: Exercise {}
var displayedExercises = Set<Exercise>()
let strengthExercises = Set<StrengthExercise>()
let cardioExercises = Set<CardioExercise>()
displayedExercises = strengthExercises
public struct OrderedSet<T: Hashable> {
private var contents = [T: Index]()
private var sequencedContents = Array<UnsafeMutablePointer<T>>()
public init() { }
public init<S: SequenceType where S.Generator.Element == T>(sequence: S) {
var gen = sequence.generate()
while let object: T = gen.next() {
if contents[object] == nil {
contents[object] = contents.count
let pointer = UnsafeMutablePointer<T>.alloc(1)
pointer.initialize(object)
sequencedContents.append(pointer)
}
}
}
public subscript(index: Index) -> T {
get {
return sequencedContents[index].memory
}
set {
contents[sequencedContents[index].memory] = nil
contents[newValue] = index
sequencedContents[index].memory = newValue
}
}
public func indexOfObject(object: T) -> Index? {
if let index = contents[object] {
return index
}
return nil
}
public var count: Int {
return contents.count
}
public var isEmpty: Bool {
return count == 0
}
public func contains(object: T) -> Bool {
return contents[object] != nil
}
mutating public func append(object: T) {
if contents[object] != nil {
return
}
contents[object] = contents.count
let pointer = UnsafeMutablePointer<T>.alloc(1)
pointer.initialize(object)
sequencedContents.append(pointer)
}
mutating public func appendObjects<S: SequenceType where S.Generator.Element == T>(objects: S) {
var gen = objects.generate()
while let object: T = gen.next() {
append(object)
}
}
mutating public func remove(object: T) {
if let index = contents[object] {
contents[object] = nil
sequencedContents[index].dealloc(1)
sequencedContents.removeAtIndex(index)
for (object, i) in contents {
if i < index {
continue
}
contents[object] = i - 1
}
}
}
mutating public func removeObjects<S: SequenceType where S.Generator.Element == T>(objects: S) {
var gen = objects.generate()
while let object: T = gen.next() {
remove(object)
}
}
mutating public func removeObjectAtIndex(index: Index) {
if index < 0 || index >= count {
fatalError("Attempting to remove an object at an index that does not exist")
}
remove(sequencedContents[index].memory)
}
mutating public func removeAllObjects() {
contents.removeAll()
sequencedContents.removeAll()
}
public func map<U: Hashable>(transform: (T) -> U) -> OrderedSet<U> {
var result = OrderedSet<U>()
for object in self {
result.append(transform(object))
}
return result
}
public var first: T? {
return count > 0 ? self[0] : nil
}
public var last: T? {
return count > 0 ? self[count - 1] : nil
}
mutating public func swapObject(first: T, withObject second: T) {
if let firstPosition = contents[first] {
if let secondPosition = contents[second] {
contents[first] = secondPosition
contents[second] = firstPosition
sequencedContents[firstPosition].memory = second
sequencedContents[secondPosition].memory = first
}
}
}
public func intersectsSequence<S: SequenceType where S.Generator.Element == T>(sequence: S) -> Bool {
var gen = sequence.generate()
while let object: T = gen.next() {
if contains(object) {
return true
}
}
return false
}
public func isSubsetOfSequence<S: SequenceType where S.Generator.Element == T>(sequence: S) -> Bool {
for (object, _) in contents {
if !sequence.contains(object) {
return false
}
}
return true
}
mutating public func moveObject(object: T, toIndex index: Index) {
if index < 0 || index >= count {
fatalError("Attempting to move an object at an index that does not exist")
}
if let position = contents[object] {
if position == index {
return
}
let adjustment = position < index ? -1 : 1
let range = index < position ? index..<position : position..<index
for (object, i) in contents {
if i < range.startIndex || i > range.endIndex || i == position {
continue
}
let originalIndex = contents[object]!
let newIndex = i + adjustment
let firstObject = sequencedContents[originalIndex].memory
let secondObject = sequencedContents[newIndex].memory
sequencedContents[originalIndex].memory = secondObject
sequencedContents[newIndex].memory = firstObject
contents[object] = newIndex
}
contents[object] = index
}
}
mutating public func moveObjectAtIndex(index: Index, toIndex: Index) {
if ((index < 0 || index >= count) || (toIndex < 0 || toIndex >= count)) {
fatalError("Attempting to move an object at or to an index that does not exist")
}
moveObject(self[index], toIndex: toIndex)
}
mutating public func insertObject(object: T, atIndex index: Index) {
if index > count || index < 0 {
fatalError("Attempting to insert an object at an index that does not exist")
}
if contents[object] != nil {
return
}
append(object)
for i in Range(start: index, end: count-1) {
swapObject(self[i], withObject: self[i+1])
}
}
mutating public func insertObjects<S: SequenceType where S.Generator.Element == T>(objects: S, atIndex index: Index) {
if index > count || index < 0 {
fatalError("Attempting to insert an object at an index that does not exist")
}
var addedObjectCount = 0
var gen = objects.generate()
while let object: T = gen.next() {
if contents[object] == nil {
let seqIdx = index + addedObjectCount
let element = UnsafeMutablePointer<T>.alloc(1)
element.initialize(object)
sequencedContents.insert(element, atIndex: seqIdx)
contents[object] = seqIdx
addedObjectCount++
}
}
for i in index + addedObjectCount..<count {
contents[sequencedContents[i].memory] = i
}
}
}
extension OrderedSet: MutableCollectionType {
public typealias Index = Int
public typealias _Element = T
public typealias Generator = OrderedSetGenerator<T>
public func generate() -> Generator {
return OrderedSetGenerator(set: self)
}
public var startIndex: Int {
return 0
}
public var endIndex: Int {
return count
}
}
public struct OrderedSetGenerator<T: Hashable>: GeneratorType {
public typealias Element = T
private var generator: IndexingGenerator<Array<UnsafeMutablePointer<T>>>
public init(set: OrderedSet<T>) {
generator = set.sequencedContents.generate()
}
mutating public func next() -> Element? {
return generator.next()?.memory
}
}
public func +<T: Hashable, S: SequenceType where S.Generator.Element == T> (lhs: OrderedSet<T>, rhs: S) -> OrderedSet<T> {
var joinedSet = lhs
joinedSet.appendObjects(rhs)
return joinedSet
}
public func +=<T: Hashable, S: SequenceType where S.Generator.Element == T> (inout lhs: OrderedSet<T>, rhs: S) {
lhs.appendObjects(rhs)
}
public func -<T: Hashable, S: SequenceType where S.Generator.Element == T> (lhs: OrderedSet<T>, rhs: S) -> OrderedSet<T> {
var purgedSet = lhs
purgedSet.removeObjects(rhs)
return purgedSet
}
public func -=<T: Hashable, S: SequenceType where S.Generator.Element == T> (inout lhs: OrderedSet<T>, rhs: S) {
lhs.removeObjects(rhs)
}
extension OrderedSet: Equatable { }
public func ==<T: Hashable> (lhs: OrderedSet<T>, rhs: OrderedSet<T>) -> Bool {
if lhs.count != rhs.count {
return false
}
for object in lhs {
if lhs.contents[object] != rhs.contents[object] {
return false
}
}
return true
}
var displayedExercises1 = OrderedSet<Exercise>()
let strengthExercises1 = OrderedSet<StrengthExercise>()
let cardioExercises1 = OrderedSet<CardioExercise>()
displayedExercises = strengthExercises
dispatch_async()
添加到主队列也是一个好主意。我更喜欢这种方式,因为只需要写一次,新的开发人员接手时就不必学习额外的东西。也许你应该把这个作为答案呈现出来?如果没有人提供一个解释错误原因的答案,我可以接受你的答案 :) - kylejsdisplayedExercises
被表视图数据源回调所使用,因此如果有任何东西从除主线程之外的任何地方设置该变量,则reloadData()
调用在错误的线程上将是你遇到麻烦的最少问题 —— 你将同时修改一个集合!因此,要么你认为displayedExercises
只会在主线程上设置,那么dispatch_async
是不必要的;或者如果它被多个线程调用,则需要在整个应用程序中进行额外的同步。 - Nicholas H.