-2

I need to do this, but I'm having all sorts of problems:

class MyClass {
}

class SomeClass {
  func callMethod(object) {
    let theType = object.type // I need the same result as MyClass.self
    let newInstance = object() // I need the same result as MyClass()
  }
}

let someClass = SomeClass()
let object = MyClass
someClass.callMethod(object)

How do you actually do this?

I want to be able to specify one type (e.g. MyClass). That can be either the type name or an instance of it and then get the two values shown in the code comments.

It would be a lot easier if I passed in two separate variables, but I'm sure I can do it in one.

nhgrif
  • 61,578
  • 25
  • 134
  • 173
user2143356
  • 5,467
  • 19
  • 51
  • 95
  • If "It would be a lot easier" why not do that. Keep in mind that code needs to be written for clarity so the next developer will easily understand it. That other developer may be you in a year or so. ;-) [Brian Kernigan](https://en.wikipedia.org/wiki/Brian_Kernighan): "Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?" – zaph Oct 02 '15 at 22:07
  • It's easier because I'm learning the Swift language. I want to learn and do it properly, even if it initially takes me longer. Not learning something properly will cause you problems in the long run. – user2143356 Oct 02 '15 at 22:30
  • What you're asking for is impossible. Because of [the way Swift initializers inherit](http://stackoverflow.com/a/32108404/2792531), you can't make any assumptions about what initializers will be available for any type obtained via the `dynamicType` property. The default zero-argument constructor is not guaranteed to exist for any class in Swift (even if it inherits from a superclass which does implement that initializer). – nhgrif Oct 02 '15 at 23:34
  • @nhgrif You are correct in the general sense. But, if you apply a type to the object parameter above of NSObject, the code compiles. It does not compile for the AnyObject type, however. You would get a runtime exception if you passed a type that did not have the init method you were calling, though. – Charles A. Oct 02 '15 at 23:43
  • 1
    I would highly recommend that you get your code reviewed. Trying to instantiate an object like this seems highly suspicious. – nhgrif Oct 03 '15 at 00:06

1 Answers1

-1

You can use the .dynamicType property of an instance to get its type. Then you can call a required init method on it (or any other class/static method).

let theType = object.dynamicType
let newInstance = theType.init()

Note: This code compiles, depending on the type of object. If the type has a required init() method, it is safe to call on the dynamicType. However, it also appears that if the type is NSObject the compiler will let you call init() on the dynamicType even though a subclass may or may not have an init() method given how Swift initializer inheritance works. Arguably this is a bug in the compiler, so use this code with caution if you choose to do so. Thanks to @nhgrif for the discussion on the topic.

Charles A.
  • 10,685
  • 1
  • 42
  • 39
  • The object isn't guaranteed to have an `init()` method. What the asker is asking for is impossible. – nhgrif Oct 02 '15 at 23:31
  • There are no types of consequence specified in the question, so my assumption is that the asker controls the objects that are passed to the method. Given that he wants to call init() on it, presumably it has that initializer. – Charles A. Oct 02 '15 at 23:34
  • It's a presumption you **cannot** make, and I'm going to assume that your code wouldn't even compile (I'm downloading Xcode onto a new machine at the moment, and then I will confirm). No object is guaranteed to have a zero argument initializer in Swift (even if it inherits from an object which does), and as such, I'd be extraordinarily surprised to learn that your snippet even compiles. – nhgrif Oct 02 '15 at 23:35
  • The asker's code wouldn't compile because the object parameter had no type specified, so that isn't exactly a relevant point. If it compiles for the poster, than his types allow for it. It compiled for me in the context I tested it. – Charles A. Oct 02 '15 at 23:36
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/91218/discussion-between-charles-a-and-nhgrif). – Charles A. Oct 02 '15 at 23:47