-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Description
| Previous ID | SR-1176 |
| Radar | rdar://24975479 |
| Original Reporter | @ffried |
| Type | Bug |
| Status | Resolved |
| Resolution | Done |
Attachment: Download
Environment
Xcode Version 7.3 (7D175)
OS X Version 10.11.4 (15E65)
Additional Detail from JIRA
| Votes | 6 |
| Component/s | Compiler |
| Labels | Bug |
| Assignee | None |
| Priority | Medium |
md5: 10b769def9e1e1f271c406d677bd5b09
duplicates:
Issue Description:
When using a generic struct (WeakContainer<T>) where the generic type needs to inherit from AnyObject, it can't be created by passing a protocol (declared by inheriting from class) for the generic type T, although no other object than one that inherits from AnyObject can implement said protocol.
Steps to Reproduce:
- Create a generic type (e.g.
struct WeakContainer<T: AnyObject>) with a generic type that needs to inherit fromAnyObject - Create a protocol which inherits from class (e.g.
MyDelegate: class). - Try to declare a variable of the generic type passing the protocol as generic parameter (e.g.
WeakContainer<MyDelegate>)
Expected Results:
It should work without any errors since the only objects which are able to implement the protocol (e.g. MyDelegate) are classes which also implement AnyObject.
Actual Results:
Instead Xcode shows an error stating that the protocol can't be used as a concrete type conforming to AnyObject. (e.g.: Using MyDelegate as concrete type conforming to protocol AnyObject is not supported)
Full source code (also attached as playground):
//: ## WeakContainer.swift
// Protocol for a container which stores objects weakly. Protocol is necessary to use it e.g. in SequenceType extensions.
public protocol WeakContainerType {
associatedtype ObjectType: AnyObject
weak var storedObject: ObjectType? { get }
}
// A concrete implementation of a WeakContainerType.
// Generic type T needs to be an AnyObject to conform to WeakContainerType's ObjectType
public struct WeakContainer<T: AnyObject>: WeakContainerType {
public typealias ObjectType = T
public private(set) weak var storedObject: ObjectType?
public init(_ object: ObjectType) {
storedObject = object
}
}
//: ## MyImplementation.swift
// A delegate which needs to be implemented by a class (aka AnyObject).
protocol MyDelegate: class {
init()
}
// A class that implemented MyDelegate correctly
class MyClass: MyDelegate {
required init() {}
}
// An instance of MyClass
let myInstance = MyClass()
// Works fine, MyClass is an AnyObject
let weakInstance = WeakContainer(myInstance)
// Can't do that, although MyDelegate can only be implemented by classes (AnyObjects) and protocols cannot instantiated themselves.
let weakProtocolInstance: WeakContainer<MyDelegate> = WeakContainer(myInstance)
// So I also can't create an array of delegate objects.
var arrayOfContainers: [WeakContainer<MyDelegate>] = []
// Proof: A protocol can't be instantiated directly (even when it defines an initializer)
let delegateObject = MyDelegate()
// Proof: A struct cannot implement MyDelegate
struct MyStruct: MyDelegate {}
// Proof: Neither can an enum
enum MyEnum: MyDelegate {
case Test, Test2
}