Selectively loading classes in Objective-C - objective-c

I have modules but no source code from two different people which both include the same class. Is there any way to selectively load classes out of the modules so that the duplicated class doesn't collide?
Yes I am aware of this alternate solution which suggests loading and unloading and would rather do it by selectively loading classes and being done with it. What is the best way to solve an Objective-C namespace collision?

If the code is written into a .framework, you could possibly load using something like #import <myFramework/MFMyCode.h>. There's no way to selectively load a class in objective-c for iDevices, if you're on the Mac, you can use the method linked in your question.
I ran across this problem where I wanted to conditionally load a class from a project if that project existed, and to not load it if it did not. Unfortunately, there's no real way to resolve this problem since imports are all done at compile time.

Related

How to organize Kotlin extension methods

Let's say I have a few extension methods for "MyClass".
My question is, what's the best practice to organize/store these methods?
Should they be simply put into a "MyClassExtensions" Kotlin file?
I have tried to encapsulate these methods within a class, but after importing the class I couldn't seem to figure out how to use/access the extension methods.
Edit:
For clarification, I was not asking for help what to call a file that contains extension methods. I was asking about best practices/approaches to store/organize such methods. Ie. should they be simply put into kotlin files, or should they be encapsulated in a class. I am coming from a Java background, so I'm used to store stuff in classes.
As far as I am concerned, you should put them into a utility file, as you did in Java code base before.
But mention, you no longer need to put them into a class. Top-level functions are the best choice.
You can refer to the kotlin standard library or some open source projects like anko, those would be good examples.
In my case, I put extensions of one class into a file which have the same name of the original file in another package, and use
#JvmMultifileClass
to reduce the number of generated class files.

How to find and remove unused class files from a project

My XCode project has grown somewhat, and I know that there are class files in there which are no longer being used. Is there an easy way to find all of these and remove them?
If the class files just sit in your project without being part of a target, just click on the project itself in the tree view, so you see all files in the table. Make sure you see the "Target" column in the table view, iterate through your targets and find the files that don't have a check anywhere -> they are no longer compiled.
But if you still compile the classes and they are no longer used, that case is a bit more difficult. Check out this project
http://www.karppinen.fi/analysistool/#dependency-graphs
You could create a dependency graph and try to find orphaned classes that way.
Edit: Link went dead, but there still seem to be projects of Objective-C dependency graphs around, for example https://github.com/nst/objc_dep
if they are C or C++ symbols, then you can just let the linker do the work for you.
if you're looking to remove objc symbols, then try to refactor the class name (e.g. to rename the class), and preview the dependencies that it turns up. if you reference classes/selectors/etc. by strings then... it may not be so effective. unfortunately, you often have to also test manually, to verify that removing a class does not break anything. remember that resources (like xibs) may reference/load objc classes as well.
This is a tricky question due to how dynamic objective-c is as you can never guarantee that a class is not going to be used.
Consider if you generate a class name and a selector at run time and then look up that class, instantiate that class and then call a method on that newly created object using that newly created selector. No where in your code do you explicitly name and instantiate that object but you are able to use it anyways. You could get that class name and selector name from anywhere outside of your code, even from some data from a server some where. How would you ever know which class is not going to be used? Because of this there are no tools that are able to perform what you are requesting.
Searching the project with the class name might be an option, thought it may not be the best solution. Specially it might be time consuming when you have many classes.

Working with the Objective-C/Cocoa flat namespace

I've not found anything that addresses my specific name space question as yet.
I am working on some AudioUnit plug-ins featuring Cocoa based GUIs. The plug-ins use a common library of user interface classes (sliders, buttons etc) which are simply added to each Xcode project.
When I recompile and distribute updates it is pretty much guaranteed that at least one user interface class will have been updated since the last release. If the user launches an older plug-in before an updated plug-in then the old Cocoa classes are already loaded into the run time and the plug-in attempts to use the older implementations - often resulting in a failure one way or another.
I know frameworks are the intended solution but the overhead and backwards compatibility issues are not ideal. I prefix all class names where possible but what options do I have to ensure that each plug-in contains unique class names for the shared user interface classes?
Update:
The solution I seem to be arriving at is as follows:
Set a preprocessor compiler flag e.g. OBJC_PREFIX=1.
Create a header file to contain all the class name redefinitions and conditionally include it in the header of each class you want to 'rename' e.g:
#ifdef OBJC_PREFIX
#include "CocoaPrefixHeader.h"
#endif
#interface MySlider : ... etc
Fill the header file (in this case CocoaPrefixHeader) with something like the following:
#define MySlider Prefix_MySlider
#define MyButton Prefix_MyButton
Using ibtool convert all your class names in an existing nib/xib file to the new names e.g:
ibtool --convert MySlider-Prefix_MySlider nibfile.xib --write nibfile2.xib
ibtool --convert MyButton-Prefix_MyButton nibfile2.xib --write nibfile2.xib
This last step converts all class names and outlets etc in the nib file. Once converted you can edit the nib as normal and IB keeps track of the redefined names.
This process is tedious and laborious but it is working for me. Far better to cater for it at the outset.
In your pre-compiled header (.pch) file for each plug-in, you can #define the classes to have different names, e.g.:
#define ClassNameUsedInYourCode ClassNameCompiledInThisProject
#define WidgetButton WahWahPedalPluginWidgetButton
As long as you're creating your UI programmatically, this will ensure that the class names are unique per-plugin. Unfortunately this won't work if you have class names baked into nib files.
In that case, you'd probably need to have some sort of pre-processing script that runs before compilation and replaces any instances of the shared class names with the project-specific class names in all files in the project, including the .xib files. This could get pretty messy but I can't see too many options.
I had a similar issue. I needed to have more than one version of the same bundle running in the same application space at the same time (I can't even remember why). It was not easy, I discussed my problems and options on the Objective-C mailing list. In the end, I modified the build-environment to:
Scan every header for classes declared with #interface.
Create a new header filled with only preprocessor macros that redefine classnames from MyClass to MyClass_v1_00 (or whatever version was defined by the Info.plist file). This header was called ClassRenamer.h.
As an intermediate build step, parse all xib XML files and replace references of MyClass to MyClass_v1_00. This doesn't modify the original xib files, which is handy.
Modify the command-line build flags to include ClassRenamer.h for all .m files.
Surprisingly, everything works perfectly, both at runtime and even in the debugger. If I put a breakpoint on a particular line, it breaks on any version of the class that is loaded, and Xcode even shows the class's name as MyClass_v1_00. The biggest concern is code that looks up classes by name, i.e. using NSClassFromString.
Whilst the solution I arrived at in the updated part of the question works as the final step in a project I can't recommend it for anything where your classes are in a state of flux. I was unable to add additional outlets to classes and have them show up in IB, for example.
In the end I just duplicated my classes and added unique name prefixes for different projects. Using ibtool --convert to update the xib file made this process a lot faster.
Once things settle down maybe a framework will be a better idea.

Load class file dynamically (Objective-C)

In an effort to create a sandbox for CoreGraphics development (which currently consists of performing multiple build and run attempts in order to achieve the desired effect), I was curious if there was a way to dynamically load a class file at runtime.
Much like Java's class-loader ability, I was hoping to use NSBundle or something similar to dynamically load a class into memory.
The idea would be to setup a sandbox project and only have to compile then dynamically reload the class, without having to stop and re-run the host application.
NSBundle can be used to load code dynamically. Have a look at -load.
I don't get why you want to reload such a bundle. (You can through -unload and -load.) It feels wrong, the only code that gets called again is +load and +initialize. You should just need to create a new instance of your class.

Objective-C equivalent of Java packages?

What is the Objective-C equivalent of Java packages? How do you group and organize your classes in Objective-C?
Question 1: Objective-C equivalent of Java packages?
Objective-C doesn't have an equivalent to Java packages or C++ namespaces. Part of the reason for this is that Objective-C was originally a very thin runtime layer on top of C, and added objects to C with minimum fuss. Unfortunately for us now, naming conflicts are something we have to deal with when using Objective-C. You win some, you lose some...
One small clarification (although it's not much for consolation) is that Objective-C actually has two flat namespaces — one for classes and one for protocols (like Java's interfaces). This doesn't solve any class naming conflicts, but it does mean you can have a protocol and class with the same name (like <NSObject> and NSObject) where the latter usually adopts ("implements") the former. This feature can prevent "Foo / FooImpl" pattern rampant in Java, but sadly doesn't help with class conflicts.
Question 2: How to [name] and organize Objective-C classes?
Naming
The following rules are subjective, but they are decent guidelines for naming Objective-C classes.
If your code can't be run by other code (it's not a framework, plugin, etc. but an end-user application or tool) you only need to avoid conflicts with code you link against. Often, this means you can get away with no prefix at all, so long as the frameworks/plugins/bundles you use have proper namespaces.
If you're developing "componentized" code (like a framework, plugin, etc.) you should choose a prefix (hopefully one that's unique) and document your use of it someplace visible so others know to avoid potential conflicts. For example, the CocoaDev wiki "registry" is a de facto public forum for calling "dibs" on a prefix. However, if your code is something like a company-internal framework, you may be able to use a prefix that someone else already does, so long as you aren't using anything with that prefix.
Organization
Organizing source files on disk is something that many Cocoa developers unfortunately gloss over. When you create a new file in Xcode, the default location is the project directory, right beside your project file, etc. Personally, I put application source in source/, test code (OCUnit, etc.) in test/, all the resources (NIB/XIB files, Info.plist, images, etc.) in resources/, and so on. If you're developing a complex project, grouping source code in a hierarchy of directories based on functionality can be a good solution, too. In any case, a well-organized project directory makes it easier to find what you need.
Xcode really doesn't care where your files are located. The organization in the project sidebar is completely independent of disk location — it is a logical (not physical) grouping. You can organize however you like in the sidebar without affecting disk location, which is nice when your source is stored in version control. On the other hand, if you move the files around on disk, patching up Xcode references is manual and tedious, but can be done. It's easiest to create your organization from the get-go, and create files in the directory where they belong.
My Opinion
Although it could be nice to have a package/namespace mechanism, don't hold your breath for it to happen. Class conflicts are quite rare in practice, and are generally glaringly obvious when they happen. Namespaces are really a solution for a non-problem in Objective-C. (In addition, adding namespaces would obviate the need for workarounds like prefixes, but could introduce a lot more complexity in method invocation, etc.)
The more subtle and devious bugs come from method conflicts when methods are added and/or overridden, not only by subclasses, but also be categories, which can cause nasty errors, since the load order of categories is undefined (nondeterministic). Implementing categories is one of the sharpest edges of Objective-C, and should only be attempted if you know what you're doing, particularly for third-party code, and especially for Cocoa framework classes.
They use long names...
Article on coding style & naming in Cocoa / Objective-C
Discussion whether Obj-C needs namespaces (deleted, archive here)
See
What is the best way to solve an Objective-C namespace collision?
for a discussion of how Objective-C has no namespaces, and the painful hacks this necessitates.
Unfortuantely objective c doesn't have any equivalent to namespace of C#,c++ and package of java....
The naming collisions could be solved by giving contextual name for example if u gonna give a name to method it should imply the class and module that it comes in so that...these problems could be avoided.
Go through the following url to know more on naming convention as advised by apple
http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/Conventions/Conventions.html
What about something like this (inside a directory)?
#define PruebaPaquete ar_com_oxenstudio_paq1_PruebaPaquete
#interface ar_com_oxenstudio_paq1_PruebaPaquete : NSObject {
and importing it like this:
#import "ar/com/oxenstudio/paq1/PruebaPaquete.h"
PruebaPaquete *p = [[PruebaPaquete alloc] init];
and when you have name collision:
#import "ar/com/oxenstudio/paq1/PruebaPaquete.h"
#import "ar/com/oxenstudio/paq2/PruebaPaquete.h"
ar_com_oxenstudio_paq1_PruebaPaquete *p = [[ar_com_oxenstudio_paq1_PruebaPaquete alloc] init];
ar_com_oxenstudio_paq2_PruebaPaquete *p2 = [[ar_com_oxenstudio_paq2_PruebaPaquete alloc] init];
Well, I think all the other answers here seem to focus on naming collisions, but missed at least one important feature, package private access control that java package provides.
When I design a class, I find it is quite often that I just want some specific class(es) to call its methods, b/c they work together to achieve a task, but I don't want all the other unrelated classes to call those methods. That is where java package access control comes in handy, so I can group the related classes into a packaged and make those methods package private access control. But there is no way to do that in objective c.
Without package private access control I find it is very hard to avoid people writing code like this, [[[[[a m1] m2] m3] m4] m5] or [a.b.c.d m1].
Update: Xcode 4.4 introduced "An Objective-C class extension header", in my opinion, that is in some way to provide "package private access control", so if you include the extension header, you can call my "package private" methods; if you only include my public header, you can only call my public API.