0

This was discussed here; similar but not identical.

MyView is a Swift subclass of UIImageView. It compiles and its interface appears in the DerivedData/.../*-Swift.h file. But downcasting to it in Obj-C fails. The code:

MyView* myView = (MyView*)viewThatCameFromIB; 
// The Custom Class declared in IB inspector as MyView.

results in this line in the Xcode Variable Viewer:

myView  UIImageView *  0x7fc8e9417e00

This line of code executes with no failure. But sure enough, trying to use the MyView features on the myView variable crashes with unknown selector. Since the cast succeeded in Obj-C, before MyClass was ported, it should also after the port, n'est-ce pas?

I tried:

  • deleting and resetting the Custom Class in IB just in case.
  • breaking this line of code into multiple steps.

Now this worked:

  • instantiate a MyView directly with its init() method

That is, I got a MyView instance:

myView  _TtC12YadaYada11MyView *  0x7f8bc05487d0

(Consequently, I can think of a workaround: write a Swift MyView constructor that takes a UIImageView and uses it to construct itself. But I shouldn't have to. Isn't that what the downcast would do behind the scenes?)

Andrew Duncan
  • 3,553
  • 4
  • 28
  • 55
  • What custom selectors are you trying to use? I suspect the swift counterparts are formatted slightly differently. Try using autocomplete for them? – Jeshua Lacock Dec 04 '17 at 01:06
  • Also, make sure you are using @objc for the exposed functions/attributes. – Jeshua Lacock Dec 04 '17 at 01:08
  • 1
    A simpler cause might be that `viewThatCameFromIB` really *is* a UIImageView. Remember that casting doesn't change anything into anything. All the cast does is tell the compiler what type of object you expect to be dealing with. The object at run-time doesn't know and doesn't care what you thought it was going to be at compile time. – danh Dec 04 '17 at 01:39
  • @danh but they said to have set the custom class in IB... try to check if when compiling the storyboard/xib you get any warnings, like "MyView symbol not found, resetting to UIImageView" – DeFrenZ Dec 04 '17 at 13:08
  • @JeshuaLacock, it doesn't matter what selector I use. Xcode (and the runtime) think `myView` is just a plain `UIImageView`. Using @objc has no effect. – Andrew Duncan Dec 04 '17 at 19:26
  • And as @DeFrenZ pointed out, I already set (and cleared and reset) the IB Custom Class. However (new fact) I ran the app in the unported branch and found that the view as coming from IB is *already* a `MyView`. As it should be. So there is something wrong with how the Custom Class is being used in IB. (IOW danh was right. Despite what IB says is the class of `myView`.) Something like the warning message @DeFrenZ suggested. Looks like I will poke around in the .xib raw XML. – Andrew Duncan Dec 04 '17 at 19:35
  • Some more evidence. I looked at the storyboard XML and saw that the Custom Class was set correctly. But along with that were customModule and customModuleProvider. (These were not present in the Obj-C branch because module is a Swift concept.) Now, my understanding of the module setting is incomplete. [continues] – Andrew Duncan Dec 04 '17 at 20:21
  • [continued] My project has two targets: `TargetA` and `TargetB`. The second one does not run because of some assets missing. Has never been run since I forked the repo for porting. All of the `MyView`s were designated as "Inherit Module From Target". But above the checkbox `Target B` appears in gray. And was in the XML. In any case, setting the module by hand to `TargetA` had no effect. But the appearance of a (gray) target name when the checkbox says Inherit From Target seems contradictory. Could be another thread unless somebody can shed light. – Andrew Duncan Dec 04 '17 at 20:28
  • More info: I built a from-scratch test app. It is clear that when the Module setting for a Custom Class does not match the target name, our symptom appears. When they are hard-set to match, or the Inherit Module From Target is set, I get a `MyView` from IB. (And the baffling thing about the grayed-out target always set to the last target persists. Harmless?) So I claim the "answer" to this question is: set the Custom Class module property to Inherit From Target. Now why this doesn't work on my actual project is unclear. Could be other confounding factors. – Andrew Duncan Dec 04 '17 at 22:04

1 Answers1

0

The problem seems to be caused (fixed) by clearing (setting) the Inherit Module From Target boolean for the MyView view, in the Custom Class section of the Identity Inspector. At least in the from-scratch test case. In my particular porting challenge, with 3,000+ files (and 50+ MyViews), there may be confounding factors. But for now, this is the answer.

Andrew Duncan
  • 3,553
  • 4
  • 28
  • 55