how to create new class files based on existing ones - in Xcode - iphone

Is there a way to create a new class based on another which already exists in the project?
Ideally one could just make a copy of a group (which may inlude .h, .m -xib) and change whatever code on this copy to create a new class.
Currently I create a new group, create the new class with it's new name and then copy the code for these files - immediately renaming the old class name into the new class name
The alternative would be to do "Show in Finder" and create duplicates for the files, drag them back into xCode, create a new group and drag them there...
Is there some better way to do this?
ps in Eclipse there is even an explicit option in the menu for this purpose
Many thanks

I think you should use a subclass for that. Create a new Objective-C class, and choose your old class as the parent class.
Have a look a this, it may help you understand this principle if you're not familiar with it : http://www.techotopia.com/index.php/Objective-C_Inheritance
The concept of inheritance brings something of a real-world view to programming. It allows a class to be defined that has a certain set of characteristics (such as methods and instance variables) and then other classes to be created which are derived from that class. The derived class inherits all of the features of the parent class and typically then adds some features of its own.
I don't know what will happen to the xib file, but at least you can re-use your classes as much as you want !

Related

Any way to trigger creation of a list of all classes in a hierarchy in Swift 4?

Edit: So far it looks like the answer to my question is, "You can't do that in Swift." I currently have a solution whereby the subclass names are listed in an array and I loop around and instantiate them to trigger the process I'm describing below. If this is the best that can be done, I'll switch it to a plist so that least it's externally defined. Another option would be to scan a directory and load all files found, then I would just need to make sure the compiler output for certain classes is put into that directory...
I'm looking for a way to do something that I've done in C++ a few times. Essentially, I want to build a series of concrete classes that implement a particular protocol, and I want to those classes to automatically register themselves such that I can obtain a list of all such classes. It's a classic Prototype pattern (see GoF book) with a twist.
Here's my approach in C++; perhaps you can give me some ideas for how to do this in Swift 4? (This code is grossly simplified, but it should demonstrate the technique.)
class Base {
private:
static set<Base*> allClasses;
Base(Base &); // never defined
protected:
Base() {
allClasses.put(this);
}
public:
static set<Base*> getAllClasses();
virtual Base* clone() = 0;
};
As you can see, every time a subclass is instantiated, a pointer to the object will be added to the static Base::allClasses by the base class constructor.
This means every class inherited from Base can follow a simple pattern and it will be registered in Base::allClasses. My application can then retrieve the list of registered objects and manipulate them as required (clone new ones, call getter/setter methods, etc).
class Derived: public Base {
private:
static Derived global; // force default constructor call
Derived() {
// initialize the properties...
}
Derived(Derived &d) {
// whatever is needed for cloning...
}
public:
virtual Derived* clone() {
return new Derived(this);
}
};
My main application can retrieve the list of objects and use it to create new objects of classes that it knows nothing about. The base class could have a getName() method that the application uses to populate a menu; now the menu automatically updates when new subclasses are created with no code changes anywhere else in the application. This is a very powerful pattern in terms of producing extensible, loosely coupled code...
I want to do something similar in Swift. However, it looks like Swift is similar to Java, in that it has some kind of runtime loader and the subclasses in this scheme (such as Derived) are not loaded because they're never referenced. And if they're not loaded, then the global variable never triggers the constructor call and the object isn't registered with the base class. Breakpoints in the subclass constructor shows that it's not being invoked.
Is there a way to do the above? My goal is to be able to add a new subclass and have the application automatically pick up the fact that the class exists without me having to edit a plist file or doing anything other than writing the code and building the app.
Thanks for reading this far — I'm sure this is a bit of a tricky question to comprehend (I've had difficulty in the past explaining it!).
I'm answering my own question; maybe it'll help someone else.
My goal is to auto initialize subclasses such that they can register with a central authority and allow the application to retrieve a list of all such classes. As I put in my edited question, above, there doesn't appear to be a way to do this in Swift. I have confirmed this now.
I've tried a bunch of different techniques and nothing seems to work. My goal was to be able to add a .swift file with a class in it and rebuild, and have everything automagically know about the new class. I will be doing this a little differently, though.
I now plan to put all subclasses that need to be initialized this way into a particular directory in my application bundle, then my AppDelegate (or similar class) will be responsible for invoking a method that scans the directory using the filenames as the class names, and instantiating each one, thus building the list of "registered" subclasses.
When I have this working, I'll come back and post the code here (or in a GitHub project and link to it).
Same boat. So far the solution I've found is to list classes manually, but not as an array of strings (which is error-prone). An a array of classes such as this does the job:
class AClass {
class var subclasses: [AClass.Type] {
return [BClass.self, CClass.self, DClass.self]
}
}
As a bonus, this approach allows me to handle trees of classes, simply by overriding subclasses in each subclass.

Eclipse 4 RCP - how to change what is showed in specific area?

I have splitted my application into two main areas.
Part(A)
PartStashContainer(B)
The content of A should be set based on what user wants.
So basically i can have 1..N classes which could be used in Class URI of Part in application model.
I don't know if i should replace the whole Part(A) with new dynamically created Part(C) which has content i want, or i should somehow to modify the existing Part (call setContributionURI, or setObject methods on Part object?).
It does make more sense to me to modify the existing Part, because it is defined in Application model and therefore already describing the location where the content should be.
Possible solutions:
Modify the Part object so it "reload" its content based on new setup (But how? Can setContributionURI or setObject methods help?)
Remove the old Part and add dynamically on same place in Application model the new Part (using EModelService and EPartService).
other solution??
If you want to reuse the Part then do something like:
MPart part = find or inject your part
MyClass myClass = (MyClass)part.getObject();
... call a method of MyClass to change the contents
MyClass is the class you specify for the object in the application model. You should add a method to that to let you change the contents.
Don't try to call setObject, this is really only for use by Eclipse. I don't think setContributionURI would do anything after the part is created (but I am not sure).
If you want to use different classes for the different data then you really should use different Parts.

How to get an IType from a class name in Eclipse JDT

I'm implementing a variant of the JUnit New Test Suite Wizard, and instead of getting test classes from the current project, I need to get them from another source. They come to me as strings of fully-qualified class names.
Some of them may not yet exist in this user's workspace, let alone in the classpath of the current project. The user will need to import the projects for these later, but I don't want to mess with that in my wizard yet. I need to just add all classes to the new suite whether they exist yet or not.
For those classes that are already in this project's classpath, I can use IJavaProject.findType(String fullyQualifiedName) . Is there an analogous way to get ITypes for classes that are not (yet) visible?
I would be happy to construct an IType out of thin air, but ITypes don't seem to like being constructed.
I don't think that is possible: the Java Document Model interfaces are created based on the classpath.
Even worse, if the project do not exist in the users workspace, the resulting code would not compile, and that is another reason for not allowing the arbitrary creation of such constructs.
If I were you, I would try to help the user to import the non-existing projects in case of types are not available, thus avoiding the tackling with the Java Document Model.
For my purposes, creating a HypotheticalType and a HypotheticalMethod got the job done. I'm attaching an overview in case anyone else needs to follow this path.
First I created a HypotheticalType and had it implement the IType interface. I instantiated one of these at the proper spot in my modified wizard. Using Eclipse's Outline view I created a method breakpoint on all methods in my new class. This let me detect which methods were actually getting called during execution of my wizard. I also modified the constructor to take, as a String, the name of the class I needed the wizard to handle.
Almost all of the new methods are ignored in this exercise. I found that I could keep the default implementation (return null or return false in most cases) for all methods except the following:
the constructor
exists() - no modification needed
getAncestor(int) - no modification needed, but it might be useful to return the package of my hypothetical class, e.g. if my class is java.lang.Object.class, return java.lang.
getDeclaringType() - no modification needed
getElementName() - modified to return the class name, e.g. if my class is java.lang.Object.class, return Object.
getElementType() - modified to return IJavaElement.TYPE
getFlags() - not modified yet, but might be
getMethod(String, String[]) - modified to return a new HypotheticalMethod(name)
getMethods() - modified to return new IMethod[] { new HypotheticalMethod("dudMethod") }
In the process I discovered that I need to be able to return a HypotheticalMethod, so I created that type as well, inheriting from IMethod, and used the same techniques to determine which methods had to be implemented. These are the only methods that get called while this wizard runs:
The constructor - add a String parameter to bring in the name of the method
exists() - no modification needed
isMainMethod() - no modification needed
That covers the solution to my original question. Zoltán, I'll be doing as you suggested in an upcoming iteration and trying to assist the user in both the case in which the desired class is not yet in this project's classpath, and the case in which the desired class is in some project not yet in the workspace.

CodeDom - Linking multiple classes within a single Assembly

I have a C# application that I am trying to re-create through the use of CodeDom. This application has four classes inside of it. If I were to go into this applications directory, I would find the project file (App.csproj), and if I were to start this project file, all four classes would load together. Furthermore, if I were to build this application, all four classes would build together.
My Question: How on earth can I create this functionality through the use of CodeDom?
I have sucessfully created one of the four classes using CodeDom, but how can I go about creating the next three classes (and linking them) to the first class that I already created?
I know this may sound confusing but I will explain more if necessary.
If the classes are in the same namespace you can add them all to one CodeNamespace object and generate the code from that.
If there in different namespaces you can add the namespace of the other Classes to your first class by adding the namespaces reference of the other class's to the namespace object you are working in:-
// Add the Namespace of the other class to the current namespace onject
defaultNameSpace.Imports.Add(new CodeNamespaceImport("Project.Namespace.Namespace"));
Where defaultNameSpace is a type of CodeNamespace. The first Class you have built is added to this CodeNamespace object as below and then the code is generated from that :-
defaultNameSpace.Types.Add(mainClass);
mainClass being a type of CodeTypeDeclaration.
Hope this helps.

How can I add an existing instance to a MEF catalog?

I have an object instance, and I want to end up with a MEF catalog that contains that object instance, exported as a specific interface type. How can I do this?
TypeCatalog doesn't seem workable here, because (a) it creates a new instance instead of using an existing one, and (b) it requires the type to have an [Export] attribute. In my case, the instance comes from MEF's metadata system, so MEF creates the underlying type and I can't add attributes to it.
As far as I can tell, the usual advice is, if you've got an existing instance, you should add it to the container (e.g. via CompositionBatch), not to the catalog. But when I add this instance, I'm also adding an entire AssemblyCatalog worth of types, all in the same operation. I'll also want to be able to remove all of these types later. It makes more sense to me to bundle everything into an AggregateCatalog. That way, I can add both the assembly and the instance in one atomic operation, and I can remove them all again the same way.
For example:
// Bootstrapper code to initialize MEF:
public void Configure() {
_selectedGameCatalog = new AggregateCatalog();
var globalCatalog = new AggregateCatalog(_selectedGameCatalog);
_container = new CompositionContainer(globalCatalog);
// ... more MEF initialization ...
}
// Sometime later, I want to add more stuff to the MEF ecosystem:
public void SelectGame(Lazy<Game, IGameMetadata> entry) {
var newCatalog = new AggregateCatalog();
// Make the assembly available to import:
newCatalog.Catalogs.Add(new AssemblyCatalog(entry.Value.GetType().Assembly));
// I also want the metadata to be available to import:
IGameMetadata metadata = entry.Metadata;
newCatalog.Catalogs.Add(MakeCatalogFromInstance<IGameMetadata>(metadata));
// Replace whatever game was selected before:
_selectedGameCatalog.Catalogs.Clear();
_selectedGameCatalog.Catalogs.Add(newCatalog);
}
The part I don't know how to do is "MakeCatalogFromInstance". How can I create a catalog that contains an existing instance (registered as a specific type)?
Or, alternatively, if I'm going about this all wrong, is there a better way to plug an entire catalog and an existing instance all into MEF at the same time, with the ability to unplug them all again later and replace them with something else?
I think it's probably best to add the types to the catalog and then add the instance to the container.
Catalogs contain part definitions. Part definitions are used to create parts. (The types for this are ComposablePartDefinition and ComposablePart.) So you could theoretically write your own catalog and a part definition that always returned a part corresponding to the instance when CreatePart was called. But catalogs weren't really designed to be used this way.
For prosperity...
MEF devivides the chores of what type info is to be used (catalog) from the actual running object instances (container). To me it is a logical descicion, especially when you setup a more complex MEF environment in your application.
If you want the ability to 'change' containers on the fly, I would suggest you try to use hierarchical containers. The root catalog/container is filled with static types and any of the child containers can be filled with each specific set of meta types you need for your game.
Hope it helps,
Marc