1

Let's suppose I've a class

class Test {

}

Then in another part of the program I could do

   let testClass = NSClassFromString( "Test" ) as NSObject.Type
    let testInstance = testClass()

Is there a way to do the same thing from reference of Test itself, pass Test as a reference and then create an object from the reference

By reference I mean pass the Test itself and receiving part of the code would be able to create object out of it.

just like we used to do in Objective-C

TestClassRef = [Test class]

[[TestClassRef alloc] init]

Edit:

protocol ISomeProtocol {
    func action ()
    func init() 
}

class Test
    var classesMap = Dictionary<String,ISomeProtocol>()

    func init () {
        self.classesMap = Dictionary<String,ISomeProtocol>()
    }

   func myAction (name:String ) {
        var myClass:ISomeProtocol;

        if let myClass = self.classesMap[ name ] {
            var myInstance = myClass() as ISomeProtocol
            myInstance.action()
        } else {
            return
        }

    }
}
user2727195
  • 7,122
  • 17
  • 70
  • 118

1 Answers1

0

Yes, but you need to make some promises about the class. For example, the equivalent of your objC code is this:

let testClass: AnyClass = Test.self
let test = testClass()

That won't compile because Swift has no way to know that AnyClass has an available init(). You need to promise that it can be trivially constructed:

protocol Trivial {
   init()
}

Which means that your class must conform to that:

final class Test: Trivial {
    required init() {}
}

And then you're free to pass around and use references to the class:

func make<T: Trivial>(type: T.Type) -> T {
  return type()
}

let myType = Test.self

let something = make(myType)

(I wrap this into a function called make because some simpler examples without a function will currently cause the compiler to crash. But most of the time you want to pass this to a function anyway.)

Some more discussion on this issue coming from other directions:

Community
  • 1
  • 1
Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • 1
    why class Test is marked as final? is it necessary? can you make an instance without involving the function make? – user2727195 Sep 28 '14 at 18:27
  • let's say they all are stored inside a dictionary associated by a string (key), we retrieve by key and create an object out of it – user2727195 Sep 28 '14 at 18:36
  • See the linked discussions on why it is easiest if it's final. It doesn't have to be, but then it needs a "required" initializer. If you want to create objects based on strings, see the discussion here for my recommendations: http://stackoverflow.com/questions/25864108/how-to-instantiate-class-and-init-from-string-in-swift – Rob Napier Sep 28 '14 at 19:47
  • As I noted, you can do this without an extra function, but in some cases it will crash the compiler today. If it's not crashing the compiler, then that's fine. – Rob Napier Sep 28 '14 at 19:48
  • we are getting close, so assuming no crash, how would you rewrite (my edit) to make it work – user2727195 Sep 28 '14 at 21:28
  • Did you add to your protocol the requirement that it have init()? What errors are you getting? (BTW, Cocoa does not prefix protocols with "I", and there is no reason to use "!" when you're already using "if let") – Rob Napier Sep 28 '14 at 21:40
  • I'm new to SWIFT, added protocol definition, it says "invalid use of '()' to call a value of non-function type ISomeProtocol – user2727195 Sep 28 '14 at 22:02
  • there was some problems with the Dictionary, I fixed it, but still the same error – user2727195 Sep 28 '14 at 22:08
  • Your dictionary is of strings to objects. you want `[String: SomeProtocol.Type]`. See the above linked answer for a full example (from the 3rd comment). – Rob Napier Sep 28 '14 at 22:45
  • sorry I'm confused a bit, and unable to get it since I'm new, can you please edit your answer to suit the above the Test class, will highly appreciate your help – user2727195 Sep 28 '14 at 22:57