Can I create C functions that are only visible to my class which is broken into multiple files? - objective-c

Using a static function, I can limit the linkage of my function to the file at hand and that is perfect in many cases. But I have a class that is unwieldy as one file, but breaking it up is made more frustrating because there are functions that I would like to keep 'private' but are needed throughout.

One part of the answer must be counter-questions, such as:
Why is your class so big that it must be split up?
Are you sure your class is so big that it must be split up? (How big is 'big'?)
Are you sure you have your class properly abstracted?
Can you make the common functions into a new class that can be used by the main class you are working with? That will hide the functions behind a class interface barrier.
On the whole, if you can avoid it, do not split the class file up arbitrarily because of size constraints; keep together that which belongs together.
A Gruesome Possibility
Assuming that a split is necessary and an orthodox split (into various classes that work together) is not possible, the question becomes: how gruesome will you accept your code being? (It's already a bit gruesome since there's an awful lot of functionality in a single file; can you stand it becoming more gruesome?)
Assume your class is in 4 (or more) files.
class.h
class.c
class1.c
class2.c
The header, class.h, is orthodox - self-contained and idempotent. It is used by the outside world (meaning outside this collection of source code) to access the facilities provided by the class.
The files class1.c and class2.c contain implementations of the functions in the class. They could be given a separate, distinctive file suffix - there might be some advantages to doing so. The files are not designed to be compiled standalone; they are strictly a convenience that splits the source up because the class got too big.
The file class.c is what you compile. It contains:
#include "class.h"
Other definitions needed by the class internals.
#include "class1.c"
#include "class2.c"
Thus, although the source is split up, you actually compile a single file, class.c.
In your makefile or equivalent, you specify that class.o depends on the header and all three source files; if any of those changes, then you need to recompile the whole lot. One advantage of changing the suffix of the implementation files (class1.c and class2.c) is that they will not compile separately because the suffix is not recognized by the C (Objective-C) compiler. One downside of changing the suffix is that your syntax-aware editor won't be aware of the correct syntax highlighting for the separate files unless you tell it the file type. If you use an IDE, it may also be less than amused at this trickery.
If you work on a machine where the size of the source means it cannot all be compiled at once like this, then you are snookered. This technique does not help at all; you have to split the files up and compile them separately. In that case, really look hard at whether you can split the code cleanly into several classes which can be managed in an orthodox way.

By request, my comment on the OP as an answer:
There's no language support for this that I'm aware of... You could put all the support functions in a separate c file and only #import its header from the class implementation files? If they don't have to be C functions (for passing as callbacks to C APIs, for example) I'd reimplement them as methods on the class and declare the private interface in a separate header—each implementation file would then #import both the "public" and "private" header.

Prefix their names with output of a cryptographic RNG. Now you don't have to worry about unintentional name collisions. Problem solved. You can hide the renaming in preprocessor macros if you really like.

Related

What's a good place to put your module #imports?

So I am using the new #import module syntax introduced with the latest Xcode - I still wonder where the best place is to put them. Before, I would place library imports and very important categories in the .pch file, but now that's not necessary anymore (at least not for the native frameworks). My first idea was to create a modules.h file and do all the imports there, then include that modules.h file in the AppDelegate - but this doesn't seem right. Also, importing in the first place you need it doesn't make sense either, since you might use it in different places.
This is in fact a question about "best practices" which is - of course - a little subjective. But I think this affects a lot of people and the overall project structure. So please share your solution to this.
it sounds like you weren't doing it the best way before, In general you want as few symbols available at any one time. For a few different reasons:
less likely to make a mistake with symbols that have the same name but different values, or types... and for reasons that the compiler has to import less crap into each compilation unit.
I am not an expert on how #import has changed the compiler semantics of preprocessing and compiling, but I suspect you should still basically import things as close to the point that they will be used as possible.
I generally will not generally import any class's headers into another class's .h file.
in a .h I will forward declare any classes with #class SomeCLass and only include enough headers to satisfy the c/c++ types that I use as ivar/properties. The only exception to that being if I need to include a superclass's header or another .h for a protocol.
the rest of the includes go into the .m
I like to keep my pch pretty spartan, but if you have some utility categories or a widely used library you could include stuff in there, I tend not to... but in a smaller project you probably wont run into problems... you will run into indexing problems in projects with hundreds of source files, especially if you have some Objective-C++ units. That will end up hurting code completion and live syntax checking.

Xcode and objective c shenanigans

Baby new to Xcode, Cocoa touch and iOS development in general. And am taking the Stanford walkthrough for their iPhone class. I am a little confused at a couple of places and need to shoot my doubts to you guys:
I have two classes that I have created for my model, essentially CalculatorBrain.m and CalculatorBrain.h.
From what I gather, in Objective C, creating a class essentially consists of two functions, one is to declare the class which contains the method/messages and other variables while the other is the actual implementation for the same. From this stems two questions:
Why must I declare a class without implementing it's methods at first? (the concept seems to be borrowed from interfaces) and only then move on to implementing it .
From the above question, as I go through the walkthrough, I notice that the class declaration took place in CalculatorBrain.h whereas the methods were actually implemented in CalculatorBrain.m. I am unable to grasp the nuances of why this was done so if anybody is willing to shed some light on this, it would really help
Thanks again,
Parijat Kalia!!!
These are traditions from the C world, and they're just common practice to avoid some problems. They aren't two classes, they are the definition (in the .h file) and the implementation (in the .c or .cc file).
If you defined the class in the .c file, you couldn't refer to it elsewhere because it wouldn't be defined. You could include your .c file, but then you'd have two copies of the code. You could also use the "extern" keyword, but at this point it's kind of odd.
If you put code in the .h file, then when it's included the code gets included. This means you can get compiler errors that you have three "getMyThing" functions.
This means you can give out your headers to others without giving away your top-secret implementation (useful for making libraries), include your header without worrying about the possible multiple definitions, etc. You can also add variables and functions in the .c file which people using the header (like your other code) can't see or use, so you don't have to worry about changing it later and having compilation break.

Ability to specify more than one class declarations and definitions in objective-c interface and implementation sections respectively

I was just wondering if I have the option to specify more than one set of class declarations and definitions in the same file, without breaking it up into multiple files.
I'm guessing this is just the sign to break it up, but I was just wondering out of curiosity.
Also, bonus, when including, what is the difference between #include and #import.
Yes. The only really vital division is that a file should only be imported or compiled, not both — that is, unless all the code you feed to the compiler is in main.m, you need to have at least one header and one implementation file. The header can contain all the interface details for everything in your program and the implementation file can contain all the implementation details and it will work just like if you had separate files. You can just stack the contents of the would-be files end-to-end. That's actually what the #import and #include directives do — they literally copy the contents of the included file into the place where the directive is written.
Of course, what we're talking about here isn't a good design for a program at all.
Yes you can do that.
#import has built-in checks to prevent including the same file multiple times (avoiding stuff like #ifndef __MYHEADER_H...)
Yes you can have multiple classes in a same file but i don't prefer it. Its a good habit/good design to have classes in different files. Helps a lot in re-usability.
#import ensures that a file is only ever included once so that you never have a problem with recursive includes. I think performance may go down if use #include.

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.

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.