Skip to content

Instantly share code, notes, and snippets.

@acrosa
Created December 5, 2014 23:14
Show Gist options
  • Save acrosa/fd1e5aeeccafeb1d1a6b to your computer and use it in GitHub Desktop.
Save acrosa/fd1e5aeeccafeb1d1a6b to your computer and use it in GitHub Desktop.
protocol ClassProtocol
{
var property: SomePropertyProtocol? { get set }
}
protocol SomePropertyProtocol
{
}
class SomeClass : ClassProtocol
{
var property: SomePropertyProtocol?
}
@NachoSoto
Copy link

Let's say you have this:

class SomeClassA: ParentClass, ClassProtocol {}
class SomeClassB: ParentClass, ClassProtocol {}

How do you define a type that is/inherits from ParentClass and conforms to ClassProtocol? (which both SomeClassA, SomeClassB are).

@acrosa
Copy link
Author

acrosa commented Dec 5, 2014

I'm in a meeting with no coffee, so whatever if this is right or not:

protocol ClassProtocol {}
class ParentClass {}
class CustomClassAndProtocol : ParentClass, ClassProtocol {}

class SomeClassA: ParentClass, ClassProtocol {}
class SomeClassB: ParentClass, ClassProtocol {}

class SomeClassC : CustomClassAndProtocol {}

@NachoSoto
Copy link

That still doesn't answer my question. What type would an object have to be?

@StanTwinB
Copy link

All we have to do is create a public header in obj-c with the property as described and see what the compiler does with it.

@StanTwinB
Copy link

Interesting, it seems to just strip off the protocol

@StanTwinB
Copy link

for example in UIViewController.h

@property (nonatomic, readwrite, assign) Class<UIViewControllerRestoration> restorationClass 

the complier generates

var restorationClass: AnyObject.Type?

Maybe there is no way...

@acrosa
Copy link
Author

acrosa commented Dec 5, 2014

I still don't understand, if you want a property to conform to a particular type (that is a subclass and a protocol at the same time), why not this:

protocol ClassProtocol {}
class ParentClass {}
class CustomClassAndProtocol : ParentClass, ClassProtocol {}

protocol ClassSubclassesMustHaveProperty {
    var property: CustomClassAndProtocol? { get set }
}

class DatClass: ClassSubclassesMustHaveProperty {
    var property: CustomClassAndProtocol?
}

@NachoSoto
Copy link

Remember my example:

class SomeClassA: ParentClass, ClassProtocol {}
class SomeClassB: ParentClass, ClassProtocol {}

I can make ClassA and ClassB inherit from the more specific CustomClassAndProtocol, but I want to avoid that. Maybe ClassB will inherit from ParentClassSubclass (a subclass of ParentClass, for example.

Of course I can solve this by restricting each of the classes, but I want to avoid solving this with inheritance.

@StanTwinB
Copy link

Another example in UIInputViewController.h

@property (nonatomic, readonly) NSObject <UITextDocumentProxy> *textDocumentProxy;

is compiled to Swift as

var textDocumentProxy: NSObject { get }

If the complier can't do it, I don't think we can

@drodriguez
Copy link

Best I can do:

protocol TestProtocol {
}

class ParentClass {
}

class TestClassA : ParentClass, TestProtocol {
}

class TestClassB : ParentClass, TestProtocol {
}

class TestClassC : ParentClass {
}

class TestClassD : TestProtocol {
}

struct Test<T where T: ParentClass, T: TestProtocol> {
  var a: T.Type {
    get {
      return T.self
    }
  }
}

let t1 = Test<TestClassA>()
let t2 = Test<TestClassB>()
let t3 = Test<TestClassC>() // Type 'TestClassC' does not conform to protocol 'TestProtocol'
let t4 = Test<TestClassD>() // Type 'TestClassD' does not inherit from 'ParentClass'

If you can, I will use a little protocol helper and call it a day:

protocol ParentClassProtocol {
}

class ParentClass: ParentClassProtocol {
}

struct Test2 {
  var b: protocol<ParentClassProtocol, TestProtocol>.Protocol {
    get {
      return TestClassA.self
    }
  }
}

You can add this protocol (a tag) in an extension for classes like UIView if you need.

The truth is that protocol<> should actually be type<> and work for real types...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment