I have an objective C program which calls an API to get an objective C class that is implemented by someone else. Lets call the external object O. In my code, I need to serialize O so that it can be encoded and decoded. Can I do this, given that O doesn't implement NSCoding or NSSecureCoding?
Related
In the official documentation for Objective C 2.0 titled The Objective-C 2.0 Programming Language from Apple, released in 2009, there is a paragraph about Class Objects on page 28.
I don't understand what Class Objects are, and how to define them aside from the rest of the language and what properties they have. In the same document it's explained that everything in Objective-C 2.0 is an object, this object is basically a pointer to a struct that contains an isa field and the pointer itself is of type id.
From this I'm deducing that:
inheritance in Obj-C 2.0 basically consists in chaining those struct through the id and isa field
objects that are superclass construct the isa field in a way that it points to a nil object.
id is a valid datatype for pretty much everything in Objective C 2.0
when defining a class, everything that defines the class itself ( methods and variables ) is packed starting from after/below the isa pointer
Assuming that I got how Objective C 2.0 works, what is a class object and how is it different from the way instances are created? What kind of properties does a class object offer that an instance doesn't have ? Can you make a parallel with C or C++?
OK, so you define a class. We'll call him Charlie:
#interface Charlie : NSObject
#end
There's our little class! Since — like every other class in Obective-C — Charlie is an object, you can send it messages like [Charlie alloc] to have Charlie allocate an instance for you. This is what we mean by a class object: It's the object that represents the class you defined.
What is an object in Objective-C? Classes are defined based on this struct:
struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};
And a class is represented by a struct like this:
struct objc_class {
struct objc_class *isa;
struct objc_class *super_class;
// A bunch of other members …
}
As you can see, the both start with an isa referring to a class. So a class is just an extension of normal objects.
When Charlie creates an instance, that instance's isa will point to Charlie. But what does Charlie's isa point to? Well, it points to a metaclass. A metaclass is a strange thing — it's a special kind of class that exists just to act as a class's class. You never interact with it directly; it just does its classly duties† when you interact with its sole instance, Charlie.
So that's what we mean when we talk about a class object — it's just the object that represents the class you defined in code.
† You might be wondering what a class's duties are. Well, the obvious biggie is that it's how you create your objects. But besides that, instances in Objective-C do not hold their own methods. Instead, method resolution is done based on an object's isa, so the class's most important function, besides creating instances for you, is determining what methods your object has.
what is a class object and how it's different from the way instances
are created ? What kind of properties a class object offers that an
instance doesn't have ? Can you make a parallel with C or C++ ?
Let's try to compare with C and C++. First there is no comparison to C, because C is not object oriented, so the concept of object or class does not exist. In C++ you have classes (or objects) which you declare in your .h file, there you write the definition of the class (the name, the instance variables, and methods or functions), and then in your .cpp file you implement the methods declared in the definition.
Also in C++ you can have static variables and methods, which, as you probably know, don't belong to a specific instance of the class, we could say that they affect all instances.
In objective C, a class property or a class method is analogous to the static variables and static funcions in C++.
A class object is the way objective C encapsulates the definition of a class and makes it available at runtime. You don't necessarily instantiate class objects explicitly.
Consider this class
#interface MyObject : NSObject
{
int i;
}
- (void)myFunction;
+ (void)classFunction;
#end
You can instantiate such an object using:
MyObject *obj = [[MyObject alloc] init];
Here you're using the alloc method of the MyObject class object. Something important to understand is that you don't instantiate class Objects, the compiler creates just one object, a class object, to represent the class.
Object is a structure, that has isa field pointing to its Class. This isa allows the structure to receive Objective-C messages, which makes it an Object. Class pointed by isa is used to lookup implementations for these messages.
(Interestingly, also blocks are objects and GCD structures are too. They both can receive messages, like -copy for blocks or -description for dispatch_queue.)
Class is a structure used to look-up methods of its instances. It has a list of method implementations for their instances (-methods). Classes have an isa field, so they qualify as Objects, thus can also receive messages. isa of Class points to a Metaclass, so a Class is instance of a Metaclass. Its single instance – a singleton.
Metaclass is where I'm getting lost, but it's definitely an Object, because it has isa. Metaclass has a list of method implementations (+methods) of its single instance – the Class.
When you write this code:
#interface MYObject : NSObject
+ (void)classMethod; // Stored in Metaclass
- (void)instanceMethod; // Stored in Class
#end
You are creating a pair: Class and Metaclass.
Oh, and what is a class of Metaclass? A Root Metaclass!
And what is a class of the Root Metaclass? The Root Metaclass itself!
But then where isa of Metaclasses points to? To our old friend NSObject. Too meta, right?
Are there any disadvantages (performance or otherwise) to using Objective C objects within a C++ class with Objective C++ files? For example, the difference between using Objective C types such as NSString directly like so:
class Hello {
private:
NSString *text;
public:
Hello() { this->text = #"Hello, world!";
~Hello();
NSString* helloWorld() { return this->text; }
};
versus using standard lib C++ strings and wrapping them into NSStrings afterward. Is there any reason that directly using Objective C "types" is inferior? I've heard people recommend to keep Objective C and C++ as separate as possible and I'd like to hear the rational behind that. Either way I'll be hiding the C++ class behind a Objective C interface regardless to call it from .m files.
I don't think there is any problem with performance, however it's not clear to me why you would want to encapsulate Objective-C objects within a C++ object.
One reason to keep C++ purely C++ is so it can interact with other C++ objects, which is no longer possible once you include Objective-C objects.
In order to allow a C++ object, with an embedded Objective-C object, to be used by another C++ class (where it needs to "see" the header file) I guess you'd have to use void * or something.
I have a class, call it A that parses some data out in an NSDictionary. That class has a table view, and when a cell is selected, a new class instantiates, let's call that class B. Class B in turn instantiates class C. I want class C to receive the NSDictionary that was created in A.
Would delegates work? Would it work even though class C isn't instantiated? If that's true and it really does not, should I pass the data from A-->B-->C in the init method? Are there better message passing methods in Objective-C?
should I pass the data from A-->B-->C in the init method?
I think that's the best plan.
A really shouldn't have to worry about how B does what it does. The fact that B uses C is none of A's business. All A needs to know is that B needs the dictionary in order to do it's thing.
As it happens, B doesn't care all that much about the dictionary, but the dictionary should be part of B's job description, which is something like: Take the data you're given and display it somehow. If B deals with the dictionary by passing it directly to C, that's fine -- not something A should care about.
You could do the same thing with a delegate. A could give B a reference to itself as a data source, and B could eventually pass that on to C. It's the same process you'd have with the dictionary, so there's no real advantage in doing that if you can put everything that C needs into the dictionary. You might consider switching to delegation if A doesn't know in advance exactly what data is needed, or when you want A to be able to somehow customize the behavior of C.
I would go with passing it through the init. Alternatively depending on what kind of class "A" is. You could make it a singleton, or pass the parsed dictionary to a singleton, and then reference it directly from within "C".
I went through the source code of GNUStep's NSNumber's implementation to understand how does factory method implementation works there.
From there What I could understand was we have NSNumber with blank implementation for all initWithXYZ kind of methods. and NSTemporaryNumber was acting like an intermediate class in the hierarchy that implemented all the initWithXYZ methods where it actually created objects of specific types , autoreleased itself and returned the created object.
Also allocWithZone was overridden to avoid creation of NSNumber object and to create object of NSTemporaryNumber if it was so otherwise create objects of specific types.
What I didn't understand was, can't the same things be done by NSNumber itself ?
why give blank implementations at all , create the object of specific type and then autorelease self.
Also if we have implementations of createXYZ methods in NSNumber itself, why have initWithXYZ methods ?
If I have to implement a factory implementation for my project where say I have two mediaItems, video , audio and photo etc.
for which I have separate classes and corresponding enums which I pass to initWithMediaType who will create an object of correct child class, return it and destroy itself.
Have two classes like NSNumber and NSTemporaryNumber: say Media and TemporaryMedia, one with blank implementations other with implementations as mentioned above ?
Should I do something like this ?
Is this the way we have to implement Factory pattern in Objective C ?
My question might seem silly biut I come from a Java, C++ background where things looked different.
The purpose might be the same but I am finding it difficult to understand the way Objective C does it since it does not have abstract classes.
Link to the source:
http://www.koders.com/objectivec/fid46956186C20201706AFE1744AA7AFEEE09D1FE5A.aspx
The point is that NSNumber is a class cluster. The class you actually end up with may be an NSIntNumber, an NSFloatNumber or one of several others. They all respond to the same messages as NSNumber (and, usually in this pattern will be subclasses of it, but that isn't required) so it makes no real difference to the caller.
When you call alloc there's no way to know what sort of object to create, so a neutral type is created and returned instead. It substitutes appropriately upon receiving an appropriate init.
So this pattern is for the implementation of class clusters. You can ignore it if writing a class that provides only instances of itself.
If I have an instance of class B which is a subclass of class A, is there a way for me to turn my instance of class B into an instance of class A without explicitly writing code to do it?
I do not mean simply downcasting with the standard c syntax.
You may be able to do this with the objc runtime (see the object_setClass(id object, Class cls) in the Objective-C runtime reference. The more important point, however, is that you almost certainly do not want to do this. If your subclass does not follow the Liskov Substituion Principle, it shouldn't be a subclass (i.e. an inheritance relationship is not appropriate and you should choose some other design). You can always invoke the superclass' method implementations with [super someMethod] from within your subclass.