I have a class with an overridden method, and the method never gets called.

this is super frustrating.


I have a class, it's one of hundreds.

eariler today, it worked fine. I have made no changes. The editor seems to think I have overriden the superClass's method. (you can find that out by just doing it again and looking at the error messages)


But, when I compile. my override is never called. In the OTHER subclasses it is called.


I have cleaned and recompiled the entire project.

I have re-written the method from scratch.

I have copied the method from the super class, and pasted it into the subclass, adding the "override" key word.


this is not the first time this has happened.

Replies

And does it work now ?

Have tried using extension like below


extension ManageOfferVC
{

override func viewDidLoad()
{
super.viewDidLoad()
service.delegate = self
configureTableView(tblView) refreshControl.addTarget(self, action: #selector(refreshTableView), for: .valueChanged) tblView.insertSubview(refreshControl, at: 0)
}

}

no. which is why I am reporting this to the forums (and to Apple.) in fact, I have discovered that the issue is widespread now. several class hierarchies that I have written from scratch, have method overrides that are completely ignored by the runtime.

this is a real problem.

JD Adite : are you suggesting the extension as a test? I do not understand what you're trying for with that.

>> this is a real problem


You have to give us more information about the actual structure of your code, otherwise no one can help much. A couple of thoughts:


1. Xcode has a debugger. Is there any reason you can't use it to find out the actual class of the subclass object at the time the overridden call is made. (That is, set a breakpoint in the caller.) It is worth checking that the object that's failing was really created as the correct subclass. Then step into the call and see where it goes next.


2. If you have a protocol P, with a method M, and an extension to P that provides a default implementation of M, and your base class B conforms to P, and your base class implements its own version of method M, and a subclass C overrides M, then there are situations where C's M won't be called (depending on whether the object is referred to via a variable of static type C, B or P).


This misbehavior is a result of shadowing (a concrete implementation of M replaces the protocol default implementation of M) and overriding (the C implementation of M supersedes the B implementation of M) not working well together, and this situation should be avoided. This issue is under active discussion over on the Swift forums. It's not exactly a bug, but it's not very useful behavior either.


So, if you can give a fragment of code showing the basic structure of this method in the base class, the subclass, and any protocols that are involved, this would be a help.

Hi Quincey,

couple things: I don't think you CAN solve it. I think it is a systemmic issue with swift, or the way Swift works with Cocoa. As I said, this is not the first time I have experienced this. Now, as to the overall structure of the code, I am building a handful of frameworks, a mac document based app that loads a variety of plugins. So, there's a bunch of places where the system can just go sideways for me, and not others. But under no circumstances should any langugae that is objective in nature, ignore inheritence. I am alarmed by this behavior, and I am simply trying to sound the alram here.


ok, I think I can respond to your questions.

1. I have confirmed without any reservations that I have the class type that I am expecting. here are some of the ways that I know: My code does an "if let" where I test the type before making the calls that are being ignored. in the same sequence of method calls (in the same loop) the object that is communicating with my class, makes more than one method call, and I have stepped through watching that call succeed, and in addition I added a print command to that method, in my subclass that gets triggered without incident. and finally, I have checked the type at the breakpoint. It's my class, and it's overriden methods are being ignored.


2. very specifically, I have a framework that declares a base class. My class, the one I am dealing with at the moment (because as I mentioned... I've found others) is in the same framework. I import that framework into a Doc based Mac App, and subsequent plugins. Currently Instances that are misbehaving are children of the Document Class, and being managed by objects that are owned by the Document and the Application itself. Eventually, plugins will also interact with this class, but that is where we have the breakdown... the method that I have overridden is what starts communication with the plugin objects.


the base class's method is defined : @objc public func propertyUpdated()

the subclass's override looks like this: @objc public override func propertyUpdated()

my class is not directly derived from the base class. there is one intermediate class, and the intermediate class, does not override the method in question.

all classes are descendents of NSObject at some level or another.


there's no reference to a protocol defining this method. I'm not using _any_ protocols (of my own design, clearly there's no way to avoid using Apple protocols) in the project at all. I have found that Swift + Cocoa, doesn't like protocols or structures. I need frameworks and plugins, so I abandoned everything I did not specifically need.



this is the method in the base class:

@objc public func propertyUpdated(){
        NotificationCenter.default.post(name: NSNotification.Name(rawValue: CNDagObjPropertiesUpdated) , object: self)
    }


this is the method override in the subClass:

@objc public override func propertyUpdated(){
        self.renderer?.nodeNeedsRender(self)
        NotificationCenter.default.post(name: NSNotification.Name(rawValue: CNDagObjPropertiesUpdated) , object: self)
    }


an objective language that breaks one of the fundamental tennets of objective langugaes, under any circumstances... bugs or not... has some serious low level problems. I 'get' that swift is trying to be Post-Objective... but it isn't when you have to use Cocoa, and that means Desktop Apps are all Objective. I am very concerned that the ground is not sound here.

The chance of this being a defect in Swift in any common scenario is about 0%. Not because Swift can't be wrong, but because too many people are using this sort of override mechanism for the problem to be unnoticed.


You have a lot more going on, so it probably isn't going to be diagnosed except by examining the actual project (e.g. in a bug report). A couple more thoughts:


— Are you declaring any of the subclass method overrides in extensions? In that case, it's possible they're being implemented as an Obj-C category, and (being in a framework) it's not outside the bounds of possibility that the category isn't getting loaded.


— There might be some other subtlety happening at module or framework boundaries. This sort of thing has always been potentially problematic when using plug-ins.


— Are you using whole-module optimization (a build setting that defaults to YES in new projects)? Does it make any difference if you turn it off?


— It's just possible that some other compiler optimization is changing the behavior unexpectedly. Does it make any difference if you add the "dynamic" modifier to the base "propertyUpdated" and all its overrides? (It might be inherited, I can't remember.)


@objc public override dynamic func propertyUpdated(){


Finally, I know this isn't what you want to spend your time doing, but can you reproduce the behavior in a much smaller test project?

>I am very concerned that the ground is not sound here.


Might be a good topic on swift.org?

Hi KMT,

many of the problems I see, are only ever experienced deep in the weeds. This one, has been like a phantasm. I've seen it before, and was never able to reproduce it on a smaller scale. Then it went away. I'm not terribly versed in compiler optimisation, so i don't muck around in those settings. In short, to answer your final question: I have tried, but I have not been successful in reproducing this issue on a smaller scale. I don't doubt that something wierd is going on, and that it is due to some of these boundaries i am leveraging (framework/plugin). when I can duplicate this issue on a smaller scale... I won't need to, because I will then know what is causing this.


i did have some success with a completely different class, by doing the objC ID for the entire class : @objc(className) // above the class itself. I wound up trying this because the superclass also had it.

but that doesn't fix the issue everywhere. I've had multiple instances where overrides to instance variables are ignored (a seemingly Swift-only issue) and the solution to that was to build the functionality differently (as a function) and override that. If you're getting the idea that this is a randomly distributed issue, good.


switching the "whole-module optimization" setting does not seem to affect things.


And I am well aware that I seem to be the only person experiencing this, I am also one of the only persons I know of, doing ground up desktop App based development in swift. as well as being the only person I know of building core functionality in frameworks and plugins. I've seen first hand, some of the growing pains injected into these borders. That doesn't eliminate the possibility that it's a fundamental issue with Swift, though it might indicate that I'm trying things nobody else is trying. I haven't ruled out the possibility that I am doing something wrong, or that things like plugins and frameworks aren't perfectly supported. None of that changes the fact that inheritence is not trustworthy (even though I can't illuminate the boundaries.)


as for whether it is a good topic for swift.org... I don't know. I must confess that my ability to parse some of the things said over there is deficient. I'm largely self taught, with nobody whatsoever to bounce ideas off of, so I never developed any language skills re: swift. I'm slow to discover what lessons to learn. I get over there, and I know there is a good reason for how the phrases are carefully arranged, I just don't understand what those english words mean in that context. So, I always come away having been unable to scale a vertical wall. I chalk this up to a complete lack of robust documentation for Swift. It's not difficult to understand the basics, it is very difficult to get beyond the basics. In any case, I stay away from the deep waters, and focus on being the best doggy paddler there is, occasionally trying to add whatever I can glean from the observation of others. I cannot distibute my entire project to random strangers, and I cannot describe a simple scenario that exposes this issue. All I can do is sound the general alarm.

I don't recall ending up deep in the weeds just by dog paddling, but get your point. Just remember, all it takes is one person to raise a point. Thanks for taking the time to share so far.


As for fundamental issues, until Swift goes to ABI, I don't believe anyone should discount their singular role in it's future.


Good luck.

>> I must confess that my ability to parse some of the things said over there is deficient


That may not be entirely your fault. 😉


The issue about taking this over there is that unless you can show code, no one is likely to help you. Also, FWIW, based on your last post, I suspect the problem is actually in the Obj-C domain, and Swift is only implicated in that it masks what's going on (or doesn't have the ability to do what you would do if this were pure Obj-C).

QuinceyMorris, you are probably right. Cocoa + Swift != Swift != Cocoa, in some ways it can be less than the sum of its parts.

and like I said: being able to show code... would mean I don't need the brains over at Swift.org.


i guess my main intention of posting here, was to put a pin in it for future reference. if/when other issues are exposed that relate to this, someobody can point here and say: see? it's not isolated to just me! Because whatever is happening... it shouldn't be.


here was how I fixed this instance of the issue in a very unsatisfying way:

I added a bool to the base class, added all of the code in the subclass to the base class, and test the bool for true. in the subclass... I set the value of that bool to true. This ain't how it should be.

I encountered this today, and found that it was caused by loading a view controller from a storyboard by name... as the base view-controller class and not the derived class that it is specified as in the storyboard.

So I understand why the overridden methods wouldn't get called. What I don't understand is why, when instantiated with the exact same method, some other derived controllers' overrides DO get called.