elsurudo
elsurudo

Reputation: 3659

Define property that must be a subclass AND conform to protocol

In Swift 2.0, how can I do the equivalent of @property (nonatomic, strong) NSManagedObject*<SomeProtocol> model?

Basically, I’m trying to define a property on my class that must both be a subclass of NSManagedObject AND conform to SomeProtocol (I will be calling methods defined by both).

I saw this: https://stackoverflow.com/a/25826948/363789, but I'm not sure how I can apply this syntax to property definition...

Upvotes: 7

Views: 780

Answers (2)

Mari&#225;n Čern&#253;
Mari&#225;n Čern&#253;

Reputation: 15748

Swift 4

This is now possible in Swift 4 using the following syntax:

var myObject: NSManagedObject & SomeProtocol

Upvotes: 5

Qbyte
Qbyte

Reputation: 13243

Unfortunately Swift doesn't support such type composition yet.

Three reasonable good solutions as workaround (the third one is probably the best):

1. You can make another type with has those properties and all types have to inherit from it in order to be used as model.

class SomeManagedObject: NSManagedObject, SomeProtocol {
    // conforming to protocol
    func someMethod()
}

// type declaration
var model: SomeManagedObject

2. A more static way to solve this problem is to use generics:

class Aclass<T: NSManagedObject where T: SomeProtocol > {
    var model: T
}

Note: You don't have to care about another type which has to be the superclass but this solution is not as dynamic and abstract as the one before.

3. You could also make your own protocol and make NSManagedObject conform though an extension:

protocol ManagedProtocol {
    // if you want to access some methods/properties directly from the type
    func method()
    var variable: Int { get }

    // otherwise call all methods/properties through "managedObject"
    // this property also reduces casting if you want to have the object itself
    var managedObject: NSManagedObject { get }
}

extension NSManagedObject: ManagedProtocol {
    var managedObject: NSManagedObject { return self }
}

Now the type is abstract and can be written as:

var model: protocol<ManagedProtocol, SomeProtocol>

Upvotes: 2

Related Questions