Accessing Unknown 'ID' class method-Objective C - objective-c

RS232MsgGetEventDescriptions.h:
#define DECLARE_RS232_NEWMSG(ClassID)\
enum \
{ \
ID = ClassID \
}; \
#interface RS232MsgGetEventDescriptions : RS232Msg
{
}
#end
RS232MsgGetEventDescriptions.m
#implementation RS232MsgGetEventDescriptions
DECLARE_RS232_NEWMSG(RM_GET_EVENT_DESCRIPTIONS);
#end
EventLogs.m
-(void)event
{
service = [CServiceAppDlg alloc];
if ([service:(REMOTE_MESSAGE_ID)RS232MsgGetEventDescriptions.ID withEvent:pEvent])
{
NSLog(#"Get Event descriptions!!");
}
}
I'm getting an error like "Accessing Unknown 'ID' class method"
I should not modify the definition here.How to pass the ID.I am going to call different descriptions ID in the same way so is this declaration of ID.

The reason why you are getting a Accessing Unknown 'ID' class method error message is because you have not declared a method called ID in your class RS232MsgGetEventDescriptions.
When you say RS232MsgGetEventDescriptions.ID in your code, you are calling the property ID of object RS232MsgGetEventDescriptions, which is equivalent to [RS232MsgGetEventDescriptions ID]. However, RS232MsgGetEventDescriptions is not an object, but a class and you don't have a class method called + (REMOTE_MESSAGE_ID)ID in your class specification (you don't have it declared on the interface or implemented on the class implementation).
I would also like to point out that it is bad practice to use the dot notation for something other than a property. Since classes cannot have #properties (these are for objects) you should call this method using standard Objective-C messaging notation [RS232MsgGetEventDescriptions ID].
Xcode will still allow you to write object.methodName to call methods with no parameters, and object.methodName = value for methods that take 1 parameter. Because they are interpreted as follows:
object.methodName; // Becomes [object methodName]
object.methodName = value; // Becomes [object setMethodName:value]

Related

Overriding parameter types?

I would like to override the parameter type of a method in its subclasses, I thought generics could be used for this but that does not seem to work (at least not the way I am doing it).
abstract class A {
bool someMethod<T>(T x);
}
Then override it like so:
class B extends A {
bool someMethod<bool>(bool x) {
// error: isn't a valid override
}
}
I have had to default to using type dynamic x for the parameter type, but that forfeits runtime safety checks and means a lot of type checking whenever the method is implemented.
Is this type of extension possible?
It's possible, but not the way you do it.
What you declare is a generic method, where each invocation gets to pass the type argument to the function.
What you probably want is:
abstract class A<T> {
bool someMethod(T x);
}
class B extends A<bool> {
bool someMethod(bool x) {
return true;
}
}
That makes the type a parameter of the subclass, not the method, so each subclass can define its own type.
(Here you get into problems with Dart's covariant generics, because you can write:
A<Object> a = B();
a.someMethod("a"); // run-time error.
Your type variable occurs only in places where a value of that type is needed, not where one is provided, so casting to the superclass A<Object> make the method more permissive than it can support. The compiler inserts a run-time type check on the argument, which is what the example code here hits.)

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

How to cast an object from its base class into its subclass

I have a class User which is a subclass of class PFUser:
class User: PFUser {
var isManager = false
}
In one of my methods I receive a PFUser object and I want to cast it to a User object
func signUpViewController(signUpController: PFSignUpViewController!, didSignUpUser user: PFUser!) {
currentUser = user
}
Is this possible?
This type of casting is a downcast. Given an instance of a certain base class where you know there exist subclasses, you can try to downcast with the typecast operator as:
class Base {}
class Derived : Base {}
let base : Base = Derived()
let derived = base as Derived
Keep in mind though, that a downcast can fail:
class Base {}
class Derived : Base {}
class Other : Base {}
let base : Base = Other()
let derived = base as Derived // fails with a runtime exception
You can try a downcast using the optional form of the type as operator as?.
class Base {}
class Derived : Base {}
class Other : Base {}
let base : Base = Other()
// The idiomatic implementation to perform a downcast:
if let derived = base as? Derived {
println("base IS A Derived")
}
else {
println("base IS NOT A Derived") // <= this will be printed.
}
This can also be done by using the following:
object_setClass(baseClass, derivedClass.self)
However it is worth nothing that this uses the objc-runtime library which can introduce odd crashes if not used correctly.
If it's an instance of PFUser, and not an instance of User stored in a variable of PFUser type, no it's not possible.
You can cast an instance of a class to one of its superclasses, but you cannot do the other way (unless the cast type is the actual instance type).
I suggest to implement an initializer in User, taking a PFUser instance as parameter - if that's possible.
However, although I never attempted to do so, I think inheriting from PFUser you'll just run into troubles, as my understanding is that this class is not designed to be inherited as it is for PFObject. I'd suggest looking into making PFUser a property of User - that way you can just assign as needed.

Method returns an object of a different class

I have noticed a situation where there is a class (say: ClassA) with variable declarations and various methods. And in another class (say: Class B), there is a method(MethodofClassB()) with the return type of the method as ClassA.
so it is like:
Class A
{
variable i,j;
public int MethodA()
{
//some operation
}
}
Class B
{
variable x,y;
public static A MethodB()
{
//some operation
return obj;
}
}
1) I understand that MethodB() return an object of ClassA. Waty would be the use(the intention) of returning the object of ClassA
2) What is the reason for defining MethodB() as Public static. what would happen if static was not used for MethodB()
3)What would the returned objct look like. I mean if my method returned an integer, it would return some numerical value say '123' . If a method returns an object of a class, what would be in the returrned value.
please help me understand this with a small example
1) I understand that MethodB() return an object of ClassA. Waty would be the use(the intention) of returning the object of ClassA
Depends on what the method does, which isn't illustrated in this example. If the result of the operation is an instance of A then it stands to reason that it would return an instance of A, whatever A is.
For example, if A is a Car and B is a CarFactory then the method is likely producing a new Car. So it would return a Car that's been produced.
2) What is the reason for defining MethodB() as Public static. what would happen if static was not used for MethodB()
public allows it to be accessed by other objects. static means it's not associated with a particular instance of B. Both are subjective based, again, on the purpose of the method (which isn't defined in the example). Being static, it can be called as such:
var newInstance = B.MethodB();
If it wasn't static then an instance of B would be required:
var objectB = new B();
var newInstance = objectB.MethodB();
There are more and more implications here, including things like memory/resource usage and thread safety. All stemming from the purpose and business logic meaning of what B is and what MethodB does.
3)What would the returned objct look like. I mean if my method returned an integer, it would return some numerical value say '123' . If a method returns an object of a class, what would be in the returrned value.
It would be an instance of A. Similar to creating an instance here:
var objectA = new A();
This method also creates (or in some way gets) an instance:
var objectA = B.MethodB();
Without knowing more about what A is, what its constructor does, and what MethodB does, these two operations are otherwise the same.
First, your code is incorrect. There is no "ClassA" class. The class name is A, so the return type should be A not ClassA.
Second, the standard Java coding standards say to start methods and variables with lower case letters. So, your example should have been:
Class A
{
A anA;
B aB;
public int methodA()
{
//some operation
}
}
Class B
{
SomeType x, y;
public static A methodB()
{
//some operation
return obj;
}
}
David's answer shortly before mine is technically correct on points 1 and 2, although he also uses your mistake of calling the A type ClassA. His code for his answer to point 3, though, is incorrect and misleading. I would change his wording to this:
`3)What would the returned objct look like. I mean if my method returned an
integer, it would return some numerical value say '123' . If a method returns
an object of a class, what would be in the returrned value`.
It would be an instance of class A. Similar to creating an instance here:
A objectA = new A();
This method also creates (or in some way gets) an instance:
A objectA = B.methodB();
Without knowing more about what class A is, what its constructor does, and what methodB does, these two operations are otherwise the same.

class variable scope issue with objc / cocoa?

Compiling in XCode 3.1.3 using GCC 4, under Leopard 10.5.8, with 10.5 as my target...
I have an interface, thus:
#interface testThing : NSObject { classContaininghooHa *ttv; }
#end
And an implementation, thus:
#implementation: testThing
- (void) instanceMethodMine
{
[ttv hooHa]; // works perfectly, compiles, links, hooHa is invoked.
}
// void cFunctionMine()
// {
// [ttv hooHa]; // compiler: 'ttv' undeclared (first use in this function) "
// }
void stupidCFunctionMine((testThing *)whom) // whom is passed class 'self' when invoked
{
[whom instanceMethodMine]; // compiles, links, works. :/
}
#end
Now, my understanding -- clearly flawed -- was that if you declared a variable, class ID or otherwise, it was private to the class, but within the class, is performed essentially as a global, stored in the allocated class instance for the duration of its existence.
That's how it acts for objc methods.
But in the c function above, also written within the class, the variable appears to be invisible. The doesn't make sense to me, but there it is.
Can someone explain to me what is going on?
While you're at it, how can I declare this as an instance variable so I can use the method within a c function declared within the class scope as shown above, as well as within methods?
Insight much appreciated.
It doesn't make any difference where you are declaring/defining your "normal" c functions. They are not part of the class, they are just plain old c functions. No connection to the class whatsoever. Passing the instance they work on is a workaround if you really don't want to make this function a true objective-c method.
interface methods have full access to it's member variables. And the C function is not part of the class and so it cannot access any class variables unless it takes an class instance as the argument.
void cFunctionMine()
{
[ttv hooHa]; // compiler: 'ttv' undeclared (first use in this function)
}
Clearly cFunctionMine is not part of the interface. So it does not what ttv is to send the message hooHa.
While you're at it, how can I declare this as an instance variable so I can use the method within a c function declared within the class scope as shown above, as well as within methods?
void cFunctionMine()
{
// 1. Create an instance using alloc and init
testThing *ttv = [ [testThing alloc] init ] ;
[ttv hooHa] ;
// Now the above statement is valid. We have a valid instance to which
// message can be passed to.
// .....
[ ttv release ] ;
// release the resources once you are done to prevent memory leaks.
}