First of all, there are no namespaces in Objective-C, that's one thing. But when a project increases in size and files, and UITableCellViews and other subviews are added, naming my classes tend to become a real pain..
For example using a model named EEMSystem in a table, my natural way to name the custom UITableViewCell would be something like EEMSystemTableViewCellController.m. This creates really long class names..
Are there any guidelines for naming controllers, views and models? What guidelines are you using?
The Coding Guidelines for Cocoa have some basic advice on naming conventions in Cocoa, but it mostly relates to method names. Generally, it's not unusual that names in Cocoa are pretty long.
In your example, I would name the class either EEMSystemTableViewCell or simply EEMSystemCell. EEMSystemTableViewCellController would imply that the class is a controller although it's actually a view.
for subclasses besides UIViewController, (like custom table cells, or UIView's not associated with a vc), I use things like CustomCell.m or LoadScreenView.m etc., not sure if its standard, but it works and helps with not having 200 letter class names.
Scott Stevenson has some recommended guidelines for class naming here:
http://cocoadevcentral.com/articles/000082.php
http://cocoadevcentral.com/articles/000083.php
From that article:
Whether they're a standard part of
Cocoa or your own creation, class
names are always capitalized.
Objective-C doesn't have namespaces,
so prefix your class names with
initials. This avoids "namespace
collision," which is a situation where
two pieces of code have the same name
but do different things. Classes
created by Cocoa Dev Central would
probably be prefixed with "CDC".
If you subclass a standard Cocoa
class, it's good idea to combine your
prefix with the superclass name, such
as CDCTableView.
Stylish Objective-C programmers always prefix their classes. The prefix is typically related to the name of the application you are developing or the library that it belong to. For example, if I were writing an application name "ImageViewer", I would prefix all classes with IMV. Classes that you will use across multiple projects typically bear a prefix that is related to your name (TCT), your company's name, or a portable library (MAP, APN).
Notice that Apple's classes have prefixes, too. Apple's classes are organized into frameworks, and each framework has its own prefix. For instance, the UIButton class belong to the UIKit framework. The classes NSArray and NSString belong to the Foundation framework. (The NS stands for NeXTSTEP, the platform for which these classes were originally designed.)
For your classes, you should use three letters prefixes. Two letters prefixes are reserved by Apple for use in framework classes. Although nothing is stopping you from creating a class with two letters prefix, but you should use three letters to eliminate the possibility of namespace collisions with Apple's present and future classes.
Please check it out for details: IOS - Objective-C - Class Names
Related
Is there any way to create "private objects" when creating a framework? (meaning, classes that won't be exported outside)
I have a problem that my frameworks uses the JSON library and when projects using my framework try to also include the JSON library they get a "symbol already defined" error.
Thanks!
Yoav.
With Objective-C that's not really possible. There are some guidelines to prevent collision though, for example one should use prefixes for members that are to be 'hidden' for other people and member variables are often prefixed with a underscore as well (Apple reserves the right to use 2 underscores). Which JSON framework are you using? Perhaps consider SBJSON if you aren't using it already, it uses the prefix (SB) to prevent collision.
From Apple's documentation:
Prefixes are an important part of names in programmatic interfaces. They differentiate functional areas of software. Usually this software comes packaged in a framework or (as is the case of Foundation and Application Kit) in closely related frameworks. Prefixes protect against collisions between symbols defined by third-party developers and those defined by Apple (as well as between symbols in Apple’s own frameworks).
A prefix has a prescribed format. It consists of two or three uppercase letters and does not use underscores or “sub prefixes.” Here are some examples
NS: Foundation
NS: Application Kit
AB: Address Book
IB: Interface Builder
Use prefixes when naming classes, protocols, functions, constants, and typedef structures. Do not use prefixes when naming methods; methods exist in a name space created by the class that defines them. Also, don’t use prefixes for naming the fields of a structure
If you want to stick with the JSON library you use, and the "namespace" is the cause of the issue, consider adding a prefix to your own classes.
I've recently discovered categories and was wondering when it might be appropriate to use them in a user defined class/new class. For example, I can see the benefits of adding a category to an existing class like NSString, but when creating a new class what would be the advantage of adding a category to this rather than just implementing a normal method?
Hope this makes sense.
Many thanks
Jules
The answer isn't really any different for your own classes than it is for framework classes. If you have multiple projects, you'll likely end up sharing some classes between them. However, you may want to extend some of your classes so that they work more easily with a specific project, but not want to include those extra methods in your other projects, where they might not make sense. You can use a category to extend your class without needing to subclass.
If I understand your question correctly, creating a "new class" is always "subclassing" because you're subclassing NSObject at the very least.
You could use categories on a new class to separate out sections of responsibility of a complex class. For example, all the basic functionality (instance variables, accessors, description, etc.) can go in one file (the "main" class file) while all methods to support a protocol (such as NSTableViewDataSource) can go in another.
Some take this approach to keep things "neat". I'm a firm believer in "if it's my own custom class, all its code should be in one file" so I do not personally do this. I demarcate different logical aspects of the class' code with "#pragma mark Some Section Name" to help navigation and readability. Your mileage may vary.
Adding a Category on NSString is useful when you want to call a method on every single NSString instance you will encounter. This is a real improvement over inheritance for this kind of object because they are used by the core framework and you don't have to convert a NSString object to your subclass when you want to call your custom method.
On the other hand, you can just put methods in, no instance variables.
In the book Refactoring by Martin Fowler, he has a section titled "Introduce Foreign Method" (A server class you are using needs an additional method, but you can't modify the class.) That's what categories are good for.
That said, there are times when using a category, instead of changing the class, is appropriate. A good example on using a category, even though you could change the server class, is how Apple handled the UIViewController MediaPlayer Additions. They could have put these two methods in UIViewController itself but since the only people who would ever use them are people who are using the Media Player framework, it made more sense to keep the methods there.
In c# I use namespaces in java I use packages. Is there a way to keep classnames short in objective c?
Objective-C only has one, single global namespace. That is why you often see classes called SBJsonParser, so that the class name doesn't collide with other JsonParsers out there.
The general recommendation I have seen is to prefix your classes with either your initials or with a few initials for the project you are working on, the class name, then (sometimes) what "type" of class they are (as is the apparent convention for view controllers).
Honestly, I am right there with you Mel, I would be absolutely exhilarated for Objective-C to add some sort of namespacing feature, at least something to sort out classes a bit more (and a bit easier).
According to Apple, two to three letter prefixes should be used
when naming classes, protocols, functions, constants, and typedef structures.
Does this include classes which are not intended to be part of a framework, simply used internally in an application? I realize this is relying on other developers that develop frameworks you might be using to use prefixes, but that seems acceptable. What about Core Data entities? If I generate classes from them, shouldn't they be prefixed as well?
To be safe, use a prefix for all classes in your application. All classes are loaded into a single flat namespace in Objective-C and the prefix prevents collisions both now and in the future.
This also includes CoreData entities; they should also use the same prefix as the rest of your application's classes.
Also note that you may decide some of this code could be used elsewhere, so using prefixes now will safeguard you from potential collisions in the future.
Is the concept of the Objective-C categories in anyway similar to the concept of mixins? If so: what are the similarities? In not: what are the differences?
To the best of my understanding:
Mixins
Syntactic sugar for composition
Added by the developer of the class, not the user
Can be reused by multiple classes
Can add instance variables
Can be implemented using forwarding in Objective-C
Categories
Similar to extension methods in other languages
Usually added by the user of the class, not the developer
Used by exactly one class and its subclasses
Can't add instance variables
To be clear the answer is NO - they are not the same.
The differences are outlined by John Calsbeek in the accepted answer, but I would say the key difference is the one where mixins can be used in different classes, whereas categories always extend exactly one class - which they declare in their definition.
This is the key difference because it means the use cases for these two features are utterly different. Another way of looking at it is that, if you're coming from Ruby to Objective-C and missing your mixins, you won't find any joy with categories.
The use case for mixins is that you have some code - methods and instance variables - that you want to reuse in several classes that don't have a common superclass. You can't do that with categories.
Mixins are effectively "multiple-inheritance" of the type you don't find in Objective-C. The closest thing in objective-c is protocols, just as the closest thing Java is interfaces, but they have neither instance variables nor method bodies (in objective-C or java). So you're generally left with creating helper classes or putting code in superclasses.
The use case for objective-c categories is that you want to add methods to an existing class - even a system or library class.
I would say that mixins are more powerful, but since it's an apples-to-oranges comparison, it would be pointless.
To be accurate:
the Ruby equivalent of Categories, is to simply reopen the class you want to extend and extend it. (You can do that anywhere in Ruby, and it's effectively identical to Categories)
I'm not sure what the objective-c equivalent to Mixins is though - anyone?
[Update] A bit more searching, and no there isn't an equivalent of Mixins in Objective-C, but the enterprising Vladimir Mitrovic has created a library that effectively does it. https://github.com/vl4dimir/ObjectiveMixin
I'm in two minds as to whether to use it or not: sometimes if the language you're using doesn't support something, it's easier to work with it rather than fight it or try to import your favourite features from other languages. ("If you can't be with the programming language you love, love the one you're with").
Then again, perhaps that's just a bit to snooty of me. The whole Aspect Oriented Programming movement has been glomming features onto Java for years (but never gaining much traction, I might add, outside of JBoss). Anyway, Vladimir gets extra kudos for using Ninja Turtles in his example.
On another side node: as a relative objective-c noob, it seems to me that categories are way overused in sample code I find all over the web. It seems common practice to add static helper methods to system classes with categories, when it would be just as easy to create a helper class to house those methods in your project, with less risk of them breaking when the system class is updated or you import someone else's library with their own such categories. A common example is adding new static color methods to UIColor. Why not just add them to a local class?
The one really good use I've seen for categories is adding methods, not to system classes, but to generated classes. So when you generate classes from your core-data object model, and you want to add new constructors or other methods that really do belong in the model class, you can do it with categories, allowing you to safely regenerate the model class if you change your model, without losing your work.
In summary:
- forget about categories as a solution for mixins
- categories are good for core-data but overused and overrated otherwise
Categories are defined for a particular class, as far as I know, you can't create a category and add the methods it implements to several classes.
With a mixin, you might derive a new class from your base and the mixin, then instantiate this new class to take advantage of it.
With a category, you are effectively adding directly the base class, so that all instances of that base have access to the functionality provided by the category.