In terms of good Objective-C coding practices, if I create a function that has no state, is it better to write it as a static method of some class or as a C function?
For example, I have a special filepath retrieval method that checks the Caches directory before proceeding to the main NSBundle. I currently have it as a static method under an otherwise empty Utils class. Should this be a C function instead?
The reason I've chosen to use a static method (for now) is that a) it's consistent with Objective-C syntax, and b) the class helps to categorize the method. However, I feel like I'm cheating a little, since I could easily fill up my Util class with these stateless static methods and end up with an ugly "shell class", whose sole purpose would be to hold them.
What convention do you use? Is one "better" than the other, by some objective metric? Thank you!
If you can think of an existing class of which this might make a good method, you can inject your method into it by making an Objective-C category. This keeps your two reasons for using a static method while not polluting the class space with an extra class.
For example:
#interface NSString (MyStringCategories)
- (NSString*) myCoolMethod;
#end
// [StringCategories.m]
#import "StringCategories.h"
#implementation NSString (MyStringCategories)
- (NSString*) myCoolMethod {
// do cool stuff here
return whateverYouLike;
}
#end
Now you can send myCoolMethod to any string. Cool!
In your particular case, it sounds like a method on NSBundle might be an appropriate architecture. And don't forget, it can be a class method, so you don't need to instantiate anything in order to call your method.
This is quite a difficult question to answer because for a lot of people the answer will depend on what their personal preferences and tastes are. I personally think that if you have a function that is a function, i.e. it has nothing to do with an object, it has no internal state etc. pp. please let it be a function and do not try to wrap everything you possibly can into an object just because you are using an OO language and you can.
In order to keep my answer short let me refer to a (imo) quite good book:
http://www.gotw.ca/publications/c++cs.htm
I know that this is for C++, but there are quite a few insights that can be shared with other languages (esp. Objective-C and Objective-C++) especially from the part called "Class Design and Inheritance". There you will find an item titeled "Prefer writing nonmember nonfriend functions".
Bottom line: "Nonmember nonfriend functions improve encapsulation by minimizing dependencies[...] They also break apart monolithic classes[...] [and] improve genericity[...]".
I think there is quite some truth in that item.
If there's no class to clearly bind it to, then I use a function. I also use functions for these utility bits because they can be stripped if not used or referenced. In that regard, it's also helpful to use a function because a link error is better than a runtime error (in the even the .m was accidentally omitted from the build, or if was referenced from another externally updated method). One problem with ObjC symbols is that they do not get stripped, so they naturally carry a high amount of dependency -- all the objc methods and classes, and required category methods must exist in the final binary. That's not an issue with really small programs or libraries, but it quickly gains weight with medium/large systems and libraries.
Everything does not need to be declared in an #interface - especially with larger systems where all those declarations will really turn your interdependencies into spaghetti. Compared to methods, functions are faster, smaller, may be optimized better by the compiler or during linking, and may be stripped if not referenced.
If you need polymorphism, it just belongs in a class for organization or convenience, then a class or instance method is often a better choice.
I also minimize declaring category methods for the same reasons. When you're using functions, you can easily write a wrapper method where you need it and get the best of both worlds.
Related
If I am implementing a function that does some calculation based on certain input and returns the output without causing any side effects.
I always use Regular C functions instead of having static methods in a class.
Is there a rationale behind using static methods forcefully put into a class ?
I am not talking about methods that create singletons or factory methods but the regular methods like there:
Instead of having something like this:
+(NSString *)generateStringFromPrefixString:(NSString *)prefixString word:(NSString *)word;
won't this be better ?
NSString *generateString(NSString *prefixString, NSString *word);
In terms of efficiency also, wont we be saving, lookup for the selector to get the function pointer ?
Objective-C doesn't have such a thing as "static methods". It has class methods. This isn't just picking a nit because class methods are dispatched dynamically, not statically. And that can be one reason to use a class method rather than a function: it allows for subclasses to override it.
By contrast, that can also be a reason to use a function rather than a class method – to prevent it from being overridden.
But, in general, there's no rule that you have to use class methods. If a function suits your needs and your preferences, use a function.
I don't think it is bad design, no, but there are certain circumstances where one may be considered more appropriate than the other. The key questions are:
Does this method belong to a class?
Is this method worth adding to a class?
A class is something that is self-contained and reusable. For the method in your example, I would be tempted to answer "Yes, it does/is," because it is something specific to NSString and is a method you (presumably) want to use fairly often. Its parameters are also of type NSString. I would therefore use the message form in a class extension and #import the extension when you need it.
There are two situations (off the top of my head) where this is not really appropriate. Firstly is the situation where the method interacts specifically with other entities outside of the 'main class'. Examples of this can be found near the bottom of Apple's NSObjcRuntime.h file. These are all standard C functions. They don't really belong to a specific class.
The second situation to use a standard C function is when it will only be used once (or very few times) in a very specific circumstance. UIApplicationMain is the perfect example, and helper methods for a specific UIView subclass's -drawRect: method also come to mind.
A final point on efficiency. Yes, selector lookup is fractionally slower standard C calls. However, the runtime (Apple's at least, can't comment on GCC's) does use a caching system so that the most commonly sent messages quickly gravitate to the 'top' of the selector table.
Disclaimer: This is somewhat a question of a style and the above recommendations are the way I would do it as I think it makes code more organised and readable. I'm sure there are other equally valid ways to structure/interleave C and Objective-C code.
One important factor is testability. Does your c-functions specifically need testing? (off-course everything has to be ideally tested, but sometimes you just can test a thing by calling what calls it). If you need to, can you access those functions individually?
Maybe you need to mock them to test other functionality?
As of 2013, if you live in the Apple/Xcode/iOS/MacOS world, it is much more likely you have more built-in tools for testing things in objc than plain c. What I am trying to say is: Mocking of c-functions is harder.
I like very much C functions. At first I didn't like them to be in my good-looking objc code. After a while, I thought that doesn't matter too much. What it really matters is the context. My point is (as same as PLPiper's on NSObjcRuntime.h) that sometimes, by judging by its name or functionality, a function does not belong to any class. So there is no semantic reason to make them a class method. All this ambiguous-like thing went away when I started writing tests for code that contained several inline c functions. Now, if I need some c function be specifically tested, mocked, etc. I know it is easier to do it in objc. There are more/easier built-in tools for testing objc things that c.
For the interested: Function mocking (for testing) in C?
For sake of consistency and programmer expectation, i'd say to use Objective C style. I'm no fan of mixing calling notation and function notation, but your mileage may differ.
Objective-C categories are extremely useful, but there are some problems with this power. These come in basically two forms which I know of:
Two categories attempting to add the same convenience method. In this case, it is undefined which one is used. If you are careful - not adding too many methods or using particularly common method names - the first problem should almost never be an issue.
New methods being added to a class by a writer that clash with a category. In this case the category overrides the class method. Since the class may not be under my control, I am more worried about this problem.
Backporting changes should be fairly safe, but implementing interfaces or adding convenience methods seem more dangerous. I know that Cocoa seems to use it for convenience methods quite a lot, but then again the base class is under there control. I think maybe they are just using the categories to reduce dependencies - so a String class can have convenience methods for working in Cocoa, but if you don't use Cocoa, it isn't pulled in.
So, how safe are categories/what guidelines are there for keeping them safe?
Usually, when extending code not under your control (e.g. Foundation), it's traditional to use a prefix or suffix on the method name to avoid these sorts of collisions.
Example from Peter Hosey's perform on main thread category:
#interface NSObject (PRHPerformOnMainThread)
- (id) performOnMainThread_PRH;
#end
It's not the most beautiful solution, but if you're worried about fragility it's a good idea.
I found the Google Objective-C Style Guide useful and it includes a convention to help avoid the collisions you mention.
I have been using Objective-C for a little while but being from a static type background (C#) I think I am using it in a very static way. Declaring objects as id feels alien to me and I can't see what the benefits are. Can anyone shine a light for me to get a better understanding of this?
Objective-C is kind of a hybrid language, in which you can be as dynamic and as static as you want. You can declare all the types of all the variables if you want, you can even declare delegate variables as NSObject<Protocol>* if you want. The id type works less as a real type and more like a hint to the compiler telling him "hey, I know what I'm doing, just trust me on this", making the compiler avoid any type checking on that particular variable.
The first obvious benefit of the Objective-C type system is that container types (NSArray, NSDictionary, NSSet) accept and return id types. This removes the need for templates and generics altogether (like in C++, Java and C#).
Even better, you can actually have containers with elements of any kind inside. As long as you know what goes inside, nobody will complain if you add two NSStrings, one NSNumber and an NSValue inside the same NSArray. You can do that in other languages, but you have to use the "Object" base class, or the void* type, and then you require to box and unbox (or cast up and down) variables in order to get the same behaviour. In Objective-C you just assign, which removes the noise generated by casting operators and boxing operations. Then you can ask "respondsToSelector:" or "class" to each object, in order to know the identity and the operations you can perform with them, at runtime. In Objective-C, reflection is a first class citizen.
Another benefit is the reduced compilation times; the compilation of an Objective-C program is in general much faster than its equivalent in C++, given that there aren't that many type checks performed, and much linking is done at runtime. The compiler trusts more the programmer.
Finally, Objective-C's dynamic type system makes possible to have a tool like Interface Builder. This is the main reason why Cocoa and Cocoa Touch has faster development times; the GUI can generate code with "id" types all over the place, and this is deserialized whenever the NIB is loaded in memory. The only language that comes close to Objective-C in terms of UI design experience is C# (and VB.NET, of course) but at the price of a much heavier application.
I personally prefer to work with a more static type checking, and I even turn on the "Treat Warnings as Errors" setting in the Objective-C compiler; I've written a blog post about it:
http://akosma.com/2009/07/16/objective-c-compiler-warnings/
This is particularly useful when you are working with developers who are new to the language. It makes the compiler whine more often than usual :)
Static type system pundits might disagree with all these points, arguing that static type checking allows for "intellisense" IDEs and better maintenance in general. I worked using .NET for years (2001 - 2006) and I must say that dynamic languages tend to produce less code, are easier to read, and in general, gives more freedom to work. The tradeoff (there's always a tradeoff) is that there is less information at compile time. But as I tend to say, compilers are a poor man's suite of tests. The best thing IMHO is to have a good suite of tests, and a good bunch of human testers torturing your code to find bugs, no matter what language you choose.
Objective-C's dynamism shines not just in the fact that every object is an id. Rather, it shines in the power of the Objective-C runtime and the ease to use it. A few examples of clever uses of runtime by Apple itself:
DO allows you to set up an proxy object for an Obj-C object in a separate app / separate machine. This is done by intercepting all the message sent to the proxy object, packing it up, sending it to the other app, and invoking it there.
KVO is implemented by dynamically replacing the setter method so that it automatically notifies the observers. (Well it's in fact subtler than that...)
CoreData accessors are generated at run time for each subclass of NSManagedObject, etc.
And, you can use the runtime from your code, too. I once used it for a good effect, mimicking CoreData and generating accessors at the run time, and having only their declaration in the header file. Thus you can get the merit of both the static typing (compile time error from the declaration in the header) and the dynamism (runtime generation of methods).
Mike Ash has written an excellent series of blog posts on how the runtime works and how to use it effectively. You just have to read it! DO, KVO, message forwarding and more. There are also many other interesting posts on the net, like fun with kvc and higher-order messaging 1, 2.
It’s actually rather rare that you would need to declare an object as type id, as you should generally know what type you are expecting. Sometimes you might use an id<Protocol> type, if you don’t know the actual type of an object but know that it should conform to a specific protocol.
Is there a particular scenario you are thinking of?
Passing instance as id is common when designing action's method; connecting a button to a method, the target looks like doSomething:(id) sender;.
In this case, it allows different kind of controls to use the same action's method, without prior knowledge of what these controls will be. In the action's method code, you can test for the class of the sender or simply use its tag property, to decide what to do.
-(void) doSomething:(id) sender {
// Get the sender's tag whatever it is
int tag = [sender tag];
switch(tag) {
case 1:
// ...
break;
case 2:
// ...
break;
}
}
I'm learning Objective-C, and have a C/C++ background.
In object-oriented C++, you always need to declare your method before you define (implement) it, even if it is declared in the parent class.
In procedural-style C, IIRC, you can get away with just defining a function so long as it is only called from something else in the same compilational unit (ie. the same file) that came later on in the file (well, provided you don't declare it elsewhere with "extern").
Now, in Objective-C, it appears that you only need to declare selectors in the header file if they are going to be used by something external, and that you can make up selectors in your .m file just fine, and call them within the .m file. Also, it appears that delegate methods or inherited methods are never (re)defined.
Am I on the right track? When do you need to define a selector in Objective-C?
For Objective-C methods, the general practice is to put methods you wish to expose in the #interface section of the header file so other code can include only the .h and know how to interact with your code. Order-based "lazy declaration" works just like functions in C — you don't have to declare a method prototype unless you have a dependency that can't be resolved by ordering, but you can add method prototypes inside the #implementation if needed.
So yes, you're on the right track. Don't repeat the method prototype for inherited methods — the compiler finds it in the parent's header file. Delegate methods may be defined as prototypes in a category (tacked onto a class) and implemented as desired, but the delegate does not need to provide a method prototype, since it is already defined. (It still can if it wants to for clarity, etc.)
Since you're just learning Objective-C, the rest of this answer is much more detail than you asked for. You have been warned. ;-)
When you statically type a variable (e.g. MyClass* instead of id) the compiler will warn you when you try to call a method that a class doesn't advertise that it implements, whether it does or not. If you dynamically type the variable, the compiler won't stop you from calling whatever you like, and you'll only get runtime errors if you call something that doesn't exist. As far as the language is concerned, you can call any method that a class implements without errors at runtime — there is no way to restrict who can call a method.
Personally, I think this is actually a good thing. We get so used to encapsulation and protecting our code from other code that we sometimes treat the caller as a devious miscreant rather than a trustworthy coworker or customer. I find it's quite pleasant to code with a mindset of "you do your job and I do mine" where everyone respects boundaries and takes care of their own thing. You might say that the "attitude" of Objective-C is one of community trust, rather than of strict enforcement. For example, I'm happy to help anyone who comes to my desk, but would get really annoyed if someone messed with my stuff or moved things around without asking. Well-designed code doesn't have to be paranoid or sociopathic, it just has to work well together. :-)
That said, there are many approaches for structuring your interfaces, depending on the level of granularity you want/need in exposing interfaces to users. Any methods you declare in the public header are essentially fair game for anyone to use. Hiding method declarations is a bit like locking your car or house — it probably won't keep everyone out, but (1) it "keeps honest people honest" by not tempting them with something they shouldn't be messing with, and (2) anyone who does get in will certainly know they weren't supposed to, and can't really complain of negative consequences.
Below are some conventions I use for file naming, and what goes in each file — starting from a .m file at the bottom, each file includes the one above it. (Using a strict chain of includes will prevent things like duplicate symbol warnings.) Some of these levels only apply to larger reusable components, such as Cocoa frameworks. Adapt them according to your needs, and use whatever names suit you.
MyClass.h — Public API (Application Programming Interface)
MyClass_Private.h — Company-internal SPI (System Programming Interface)
MyClass_Internal.h — Project-internal IPI (Internal Programming Interface)
MyClass.m — Implementation, generally of all API/SPI/IPI declarations
MyClass_Foo.m — Additional implementation, such as for categories
API is for everyone to use, and is publicly supported (usually in Foo.framework/Headers). SPI exposes additional functionality for internal clients of your code, but with the understanding that support may be limited and the interface is subject to change (usually in Foo.framework/PrivateHeaders). IPI consists of implementation-specific details that should never be used outside the project itself, and these headers are not included in the framework at all. Anyone who chooses to use SPI and IPI calls does so at their own risk, and usually to their detriment when changes break their code. :-)
Declaring the methods in the header file will only stop compiler warnings. Objective-C is a dynamic language, so you can call a method (send a message) to an object whether or not that method is declared externally.
Also, if you define a method in the .m file above any code that calls it (lazy declaration) then that won't generate any warnings. However the same thing applies, you can send a message to an object without it being declared.
Of course - this means that there are no private methods in Objective-C. Any method that a class implements can be called.
Personal preference. If it's a public method (i.e one used externally). declare it in the .h and define in the .m. If you want to limit it's visibility, or at least indicate that it is a private method, use categories/class extensions in the .m file. Although lots of example code uses the lazy declaration method.
Objective-C treats functions as "messages" and as such, you can send a "message" to any object - even one that doesn't explicitly state in its interface that it can accept. As a result, there are no such things as private members in Obj-C.
This can be very powerful, but is a source of confusion for new Obj-C programmers - especially those coming from C++, Java or C#. Here are the basic rules of thumb:
You should define all public methods in your #interface so that consumers know what messages you expect to handle.
You should define #private methods in your #interface to avoid compiler messages and avoid having to order the methods in your #implementation.
You should use protocols when implementing a particular convention of methods for your class.
Much of this is personal preference, however it helps to avoid annoying compiler warnings and keeps your code organized. and easy to understand.
When reading Best way to define private methods for a class in Objective-C I end up with a programming style doubt. Which is the better solution (in terms of style) to this problem? To use a category and declare it in the #interface directive in the .m file or go with the static function that receives an object.
Thanks
Categories are the way to go.
The Google Objective-C Style Guide says,
Use a private category to prevent cluttering the public header.
…
If you are using Objective-C 2.0, you should instead declare your private category using a class extension, for example:
#interface GMFoo () { ... }
which will guarantee that the declared methods are implemented in the #implementation section by issuing a compiler warning if they are not.
"A class extension is declared just like a category, but without a name"
--Class Extensions Explained
If you do not have an immediate answer as to which to use, prefer functions.
I use functions most of the time (> 90%).
Methods are useful for polymorphism and the interface.
There are other considerations for each:
Functions will generally be smaller, faster, and the compiler has the ability to inline them. If there is no reason to cause a problem by using a method and you do not need to have any exclusive in-class use, then go with the function.
Methods (or categories, if you prefer) are handy if you don't want accessor overhead or want some other feature which is available in the instance method, such as #synchronized. In my programs, these features are far less likely, and there is usually no need to use methods.
Methods export additional symbols, and generally incur a higher (but small) overhead, as a result, they typically make the binary slightly larger and the executable slightly slower (not usually noticed, unless you use them often).
There is also a risk in using/creating private methods, in that receivers/subclasses may implement/declare the method. It's often an unnecessary risk. I prefer the compiler/linker to sort this out for me, rather than find out that it is hitting an odd case at runtime 2 weeks after shipping (and difficult to locate the problem). Methods may also be useful if you intend on making the interface public sometime soon.