Problem calling class methods (Q:1) - objective-c

I'm trying to convert an old 'C' program containing some static methods into Obj-c but I'm having a few problems getting it to compile. In the header file I've got:
#interface Anneal : NSObject
...
...
+(float)approxInitT;
-(costType)simulatedAnnealing;
...
and in the implementation file, the two problem methods (also cut-down for brevity):
#implementation Anneal
+(float)approxInitT
{
float T=0.0;
int m2=0;
...
if(m2==0)
T = T_LIFESAVER;
else
T = T / m2 / log(initProb);
return T;
}
-(costType)simulatedAnnealing
{
float T;
...
if(Tset)
T=initialT;
else
T=[self approxInitT]; // error:incompatible types in assignment
}
Unfortunately I'm getting an "incompatible types in assignment" error even though 'T' and the return from the class method are both of type 'float'. While the code contains multiple source files (from which I'm expecting to hit a few more problems in the next few days), they're both in the same one.
The problem is obviously caused by an error in the way I'm calling 'approxInitT()' but a search of the internet hasn't uncovered any answers to my prob so far.
As a novice I don't have any experience in multi-model code OR using static/class methods, and I'd sure appreciate any help with this. Thanks in advance :-)

Class methods donot belong to any particular instance of a class. So, try passing the message to class itself -
T = [ Anneal approxInitT ];

self references an instance of a particular class, but as you are calling a class method (+approxInitT), you must send the message to your class: T=[Anneal
approxInitT]

Related

Comparison operator overloading for class in D?

I am currently learning D and struggling to understand how operator overloading could work for a class? Overriding opCmp makes sense and works correctly for a struct, but for a class it requires taking the right hand side as a Object instead of as my type.
This means I can't access any members to do a comparison. What's the point in the overload then? Am I missing something?
Sure you can access your members:
class MyClass {
int member;
override int opCmp(Object other) {
if (auto mcOther = cast(MyClass)other) {
// other, and thus mcOther, is an instance of MyClass.
// So we can access its members normally:
return member < mcOther.member ? -1
: member > mcOther.member ? 1
: 0;
} else {
// other is not a MyClass, so we give up:
assert(0, "Can't compare MyClass with just anything!");
}
}
}
The reason opCmp for classes takes Object as a parameter is it's being introduced in the Object class, from which every D class derives. Introducing opCmp there was a sensible choice back in the day, but less so now. However, since we don't want to break every piece of D code out there that uses opCmp (and opEquals, toHash and toString) with classes, we're kinda stuck with that choice.

Swift class properties not initialized when constructed by Objective C code

I'm attempting to create a class in Swift 3 to implement a Cordova plugin. I have this building and running, but the application crashes whenever any properties of the class are accessed. I've tried two ways of initializing the class:
#objc(DSFMediaCentre)
class DSFMediaCentre : CDVPlugin
{
var players = [UUID:DSFPlayerHandler] ();
...
}
and
#objc(DSFMediaCentre)
class DSFMediaCentre : CDVPlugin
{
var players :[UUID:DSFPlayerHandler];
override init () {
players = [:];
}
...
}
However, when my players property is used, the result is a EXC_BAD_ACCESS exception, with an address that looks like a null pointer dereference.
The object is being created by Objective C code, which is a language I have no familiarity with at all, but I think this is the line that creates it:
obj = [[NSClassFromString(className)alloc] initWithWebViewEngine:_webViewEngine];
The CDVPlugin class contains a comment stating that initWithWebViewEngine should not be overridden (and indeed I do not seem to be able to override this method, because while it is declared in the CDVPlugin.m file, it isn't mentioned in CDVPlugin.h, so the Swift compiler doesn't seem to know about it), but rather initialization code should be placed in a method called pluginInitialize instead. However, if I do that I get a compiler error ("Class DSFMediaCentre has no initializers").
Furthermore, if I put my init() method back in and set it to call pluginInitialize(), like this:
override init () {
super.init(); // necessary otherwise next line is an error
pluginInitialize();
}
override func pluginInitialize() {
players = [:];
}
the error then changes to "Property 'self.players' not initialized at super.init call".
How do I make this class initialize correctly?
You have a mismatch between the strict initialization system required by the language and the procedure used by the framework you're working with.
Swift demands that a) properties be initialized as part of object construction, and b) that construction be chained to the type's supertype. But the CDVPlugin type is doing the construction on your behalf; you don't have the ability to customize it. (This makes more sense in ObjC, because it doesn't have the same compile-time restrictions as Swift.)
The situation is similar to unpacking an object from a nib file. In that case too, because it's the nib loading system that's constructing your object, you don't have the ability to customize the initializer. Your type will always be constructed by init(coder:). In a certain sense, your initialization point moves further down, to awakeFromNib(), and among other things, that forces outlets to other objects in the archive to be declared as optional, usually implicitly unwrapped.
The same solution should avail you here. You should consider pluginInitialize() to be your initialization point. The language then requires that properties be optional, since they are not filled at its initialization point. Therefore, make the property an IUO:
#objc(DSFMediaCentre)
class DSFMediaCentre : CDVPlugin
{
var players :[UUID:DSFPlayerHandler]!
override func pluginInitialize() {
players = [:];
}
}
and all should be well.
The other solution is to use lazy keyword
lazy var players :[UUID:DSFPlayerHandler] = [:]
So, you don't need to initialize players in initializer but still make sure players always non-nulable

Error accessing function of class while converting Obj C project to Swift

I added my swift class to the target while removing my header file of the same objective C class from the target but this error shows when I try and build my project. I can't attach an image right now but the error states: "Use of instance member 'url' on type 'ServerURLFactory'; did you mean to use a value of type 'ServerURLFactory' instead?"
let accessURL: NSURL = NSURL(string: "\(ServerURLFactory.url())/CygnetInstanceXMLServlet?cygnetId=\(idNumber)")!
print(accessURL)
Has anyone ran into a similar problem and how to fix this confusing bug? Its as if the program is still trying to call the Obj C function instead of explicitly calling the one in the Swift file.
You're calling .url() on ServerURLFactory itself as a type:
ServerURLFactory.url()
I guess you should instantiate the class first. Probably something like this, but it depends on how the class is implemented:
let factory = ServerURLFactory()
Then:
factory.url()

Yet another dynamic_class failing with "invalid target type"

I am missing something ...
I have a class SocketComm. I have a derived class SocketTCP : public SocketComm.
SocketComm has the following in it:
static SocketComm *Instance; // static pointer to the singleton instance du jour
I am trying to define a method in SocketComm as follows:
static inline SocketTCP *GetTCPclass()
{
// consistent method to return a SocketTCP* cast of SocketComm::Instance (or NULL)
SocketTCP *s = dynamic_cast<SocketTCP *>(Instance);
assert( s != NULL );
return s;
}
I am getting (VS 2010)
error C2680: 'SocketTCP *' : invalid target type for dynamic_cast
What am I missing? SocketComm is abstract -- is that the problem?
The answer seems to be that dynamic_cast needs a full declaration of the target class.
See my comment above.
Yeah, like #ViRusTriNiTy says, I suppose I could have put it in SocketTCP as a static inline. That would probably have worked too. But it seems more logical to me in the base class, and there is no performance reason to make it inline. The compiler will inline it when it can (in SocketComm.cpp) anyway.
According to your comments you are mixing code that belongs to a derived class into a base class. This is the wrong approach and you now see why: SocketTCP' : class must be defined before using in a dynamic_cast.
Just approach this in a different way like say adding a separate helper class that does the dynamic_cast.

Storing MyClass values in List

I am completely new to C++\CLI and I have the following problem: I have a class called, for example, MyClass, a few values of which I need to store in memory. I have decided to use List, because it is the most familiar to me, since I was using C# for a long time. So here goes the code:
//Header File
ref class MyClass
{
public:
MyClass(void);
private:
System::Collections::Generic::List<MyClass^> values;
};
//CPP file
MyClass::MyClass(void){
this->values=gcnew System::Collections::Generic::List<MyClass^>();
}
The compiler keeps on saying that there's an error C2582. But if there's no assignment operator, then how should I initialize the List?
Thanks in advance.
values should not be a List<...^>, but a List<...^>^. You want to assign a reference, not to create another clone of the list.