Making best use of Objective-C dynamic features - objective-c

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;
}
}

Related

Is Polymorphism a waste to apply for the classes that we exactly know the type prior run-time?

Run-time Polymorphism can be used to let the run-time to dynamically load the exact concrete class of an abstract class/interface. (You can take Animal/Dog, Vehicle/Car examples)
But when we know the exact concrete class #coding-time (compile-time), does it really need to forcefully apply polymorphism?
When I write OO code, I tend to use most-general type I can on the left-hand side of the assignment. This immediately means that my answer to your question is - no.
Here's the example:
Animal x = new Dog();
...
x.move();
The reason why I'm doing this is that I'm probably going to split beginning and end of the operation into two distinct operations. My methods are extremely short in practice.
Applied to the same example:
function moveDog() {
move(new Dog());
}
function move(Animal animal) {
animal.move();
}
As you can see, it would make no sense for the move function to know what kind of animal it is really moving.
Generally, it is compiler's duty to figure whether in a given code base any concrete call has been made with an overridden move() method. Some compilers can detect that no overridden method will be subjected to them and then they remove dynamic dispatch at compile time. With some luck, my code above would compile the same whether move function receives Animal or Dog.
Now, this is theory. In practice, there are two important things. First, compilers that are widely used have still not started using such aggressive optimization techniques as detecting static method calls, as opposed to calls that require dynamic dispatch. Second, the first thing doesn't matter too much with CPU power we have today.
I have been writing highly optimized code for fifteen years already and I have met the situation in which I had to factor polymorphic calls out. That is why I strongly recommend to apply polymorphism as much as possible. When the time comes to add some classes, to incorporate new features, polymorphic calls will likely be the tool to seamlessly add new classes to the existing design. If you used overly concrete types during development, it could easily happen that you cannot add new feature to the given code base.
But when we know the exact concrete class #coding-time (compile-time), does it really need to forcefully apply polymorphism?
Knowing the type at compile time is not necessarily a yes/no thing across all the code in an app and an object's entire lifetime, given techniques for type erasure. But, ignoring those classic uses of polymorphism, there are still other potential reasons such as...
(sorry - pretty obvious one this) to make it easier to change the implementation should another become available later
to make it easier to "mock" an implementation for testing (i.e. provide objects that pretend to provide some service or function, but have more scripted/controllable/observable behaviours to let tests put some dependent code through its paces)
hide aspects of the implementation that might otherwise have to be exposed (e.g. in C++, a class/struct definition must declare all the protected and private members)
this is sometimes for Intellectual Property protection; at other times, so more changes can be made to the implementation without having to make a change the "header" file that would typically trigger recompilation of a lot of dependent code
to aid in modelling and application design, using the "interfaces" to cleanly specify the intended APIs, which can then provide a more stable reference for comparison as the implementations are fleshed out

extending objects at run-time via categories?

Objective-C’s objects are pretty flexible when compared to similar languages like C++ and can be extended at runtime via Categories or through runtime functions.
Any idea what this sentence means? I am relatively new to Objective-C
While technically true, it may be confusing to the reader to call category extension "at runtime." As Justin Meiners explains, categories allow you to add additional methods to an existing class without requiring access to the existing class's source code. The use of categories is fairly common in Objective-C, though there are some dangers. If two different categories add the same method to the same class, then the behavior is undefined. Since you cannot know whether some other part of the system (perhaps even a system library) adds a category method, you typically must add a prefix to prevent collisions (for example rather than swappedString, a better name would likely be something like rnc_swappedString if this were part of RNCryptor for instance.)
As I said, it is technically true that categories are added at runtime, but from the programmer's point of view, categories are written as though just part of the class, so most people think of them as being a compile-time choice. It is very rare to decide at runtime whether to add a category method or not.
As a beginner, you should be aware of categories, but slow to create new ones. Creating categories is a somewhat intermediate-level skill. It's not something to avoid, but not something you'll use every day. It's very easy to overuse them. See Justin's link for more information.
On the other hand, "runtime functions" really do add new functionality to existing classes or even specific objects at runtime, and are completely under the control of code. You can, at runtime, modify a class such that it responds to a method it didn't previously respond to. You can even generate entirely new classes at runtime that did not exist when the program was compiled, and you can change the class of existing objects. (This is exactly how Key-Value Observation is implemented.)
Modifying classes and objects using the runtime is an advanced skill. You should not even consider using these techniques in production code until you have significant experience. And when you have that experience, it will tell you that you very seldom what to do this anyway. You will know the runtime functions because they are C-based, with names like method_exchangeImplmentations. You won't mistake them for normal ObjC (and you generally have to import objc/runtime.h to get to them.)
There is a middle-ground that bleeds into runtime manipulation called message forwarding and dynamic message resolution. This is often used for proxy objects, and is implemented with -forwardingTargetForSelector, +resolveInstanceMethod, and some similar methods. These are tools that allow classes to modify themselves at runtime, and is much less dangerous than modifying other classes (i.e. "swizzling").
It's also important to consider how all of this translates to Swift. In general, Swift has discouraged and restricted the use of runtime class manipulation, but it embraces (and improves) category-like extensions. By the time you're experienced enough to dig into the runtime, you will likely find it an even more obscure skill than it is today. But you will use extensions (Swift's version of categories) in every program.
A category allows you to add functionality to an existing class that you do not have access to source code for (System frameworks, 3rd party APIs etc). This functionality is possible by adding methods to a class at runtime.
For example lets say I wanted to add a method to NSString that swapped uppercase and lowercase letters called -swappedString. In static languages (such as C++), extending classes like this is more difficult. I would have to create a subclass of NSString (or a helper function). While my own code could take advantage of my subclass, any instance created in a library would not use my subclass and would not have my method.
Using categories I can extend any class, such as adding a -swappedString method and use it on any instance of the class, such asNSString transparently [anyString swappedString];.
You can learn more details from Apple's Docs

Is using C functions instead of static methods for making pure functions a bad design?

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.

Stateless static methods vs. C functions in Objective-C

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.

When do I define objective-c methods?

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.