What's the most efficient way to make immutable and mutable versions of an objective-c class? - objective-c

Suppose I’m making an Objective-C class that represents a fraction, and want to create immutable and mutable versions.
Following the patterns in the Foundation framework, you might expect to see the method fractionByAddingFraction: in the immutable version and addFraction: in the mutable version.
The paradox I’m running into is how to only include the fraction-adding logic once between the two classes. It seems that the immutable fractionByAddingFraction: method needs to know about (and make use of) the mutable addFraction: method in order to avoid code duplication, and yet including the mutable methods in the implementation of the immutable class means they could conceivably be called on the immutable object, which defeats the point.
A brief explanation (or better still, a continuation of this simplified example) would be much appreciated!

Your approach is correct (if you really need a mutable subclass, which you should avoid unless you actually need it). I'm not quite clear where the confusion is coming in. You would most easily implement addFraction: using fractionByAddingFraction:. It would be a little inefficient, but that's the direction that would make the most sense. Something like:
- (void)addFraction:(Fraction *)anotherFraction {
Fraction *newFraction = [self fractionByAddingFraction:anotherFraction];
self.internalStuff = newFraction.internalStuff;
}
But typically you would probably handle this more efficiently with some private _GetInternalStuffByAddingInternalStuffs() function that both classes would use.

The primary implementations of Foundation’s collections cheat: there’s only one implementation, which is a subclass of NSMutableFoo, and it has a private mutability flag. This means client code can’t test whether a particular object is mutable or not, but that would never be a good idea anyway except perhaps for debugging and assertions.

Related

When using reference to objects, do we have a mechanism similar to "pass by value" for callee not to be able to make any change to the original data?

For the mechanism of "pass by value", it was so that the callee cannot alter the original data. So the callee can change the parameter variable in any way, but when the function returns, the original value in the argument variable is not changed.
But in Objective-C or Ruby, since all variables for objects are references to objects, when we pass the object to any method, the method can "send a message" to alter the object. After the method returns, the caller will continue with the argument already in a different state.
Or is there a way to guarantee the passed in object not changed (its states not altered) -- is there such a mechanism?
You're somewhat misusing the term "pass by value" and "pass by reference" here. What you really are discussing is const. In C++, you can refer to a const instance of a mutable class. There is no similar concept for ObjC objects (or in Ruby I believe, though I am much less familiar with Ruby than ObjC). ObjC does, via C, have the concept of const pointers, but these are a much weaker promise.
The best solution to this in ObjC is to prefer value (immutable) classes whenever possible. See Imutability in Objective-c for more discussion on that.
The next-best solution is to, as a matter of design, avoid this situation. Avoid side effects in your methods that are not obvious from the name. By avoiding this as a matter of design, callers should not need to worry about it. Remember, the caller and the called are on the same team. Neither should be trying to protected itself from the other. Good naming and good API design help the developer avoid error without compiler enforcement. ObjC has little compiler enforcement, so good naming and good API design are absolutely critical. I would say the same for Ruby, despite my limited experience there, in that it is also a highly dynamic language.
Finally, if you are dealing with a poorly behaved API that does modify your object when it shouldn't, you can resort to passing it a copy.
But if you're designing this from scratch, think hard about using an immutable class whenever possible.
I'm not sure what you are getting at. Ruby is pass-by-value. You cannot "change the argument variable":
def is_ruby_pass_by_value?(foo)
foo = 'No, Ruby is not pass-by-value.'
return nil
end
bar = 'Yes, of course, Ruby *is* pass-by-value!'
is_ruby_pass_by_value?(bar)
p bar
# 'Yes, of course, Ruby *is* pass-by-value!'
I'm not sure about Objective-C, but I would be surprised if it were different.

Objective-C: Checking class type, better to use isKindOfClass, or respondsToSelector?

Is it more appropriate to check a class's type by calling isKindOfClass:, or take the "duck typing" approach by just checking whether it supports the method you're looking for via respondsToSelector: ?
Here's the code I'm thinking of, written both ways:
for (id widget in self.widgets)
{
[self tryToRefresh:widget];
// Does this widget have sources? Refresh them, too.
if ([widget isKindOfClass:[WidgetWithSources class]])
{
for (Source* source in [widget sources])
{
[self tryToRefresh:source];
}
}
}
Alternatively:
for (id widget in self.widgets)
{
[self tryToRefresh:widget];
// Does this widget have sources? Refresh them, too.
if ([widget respondsToSelector:(#selector(sources))])
{
for (Source* source in [widget sources])
{
[self tryToRefresh:source];
}
}
}
It depends on the situation!
My rule of thumb would be, is this just for me, or am I passing it along to someone else?
In your example, respondsToSelector: is fine, since all you need to know is whether you can send the object that message, so you can do something with the result. The class isn't really that important.
On the other hand, if you were going to pass that object to some other piece of code, you don't necessarily know what messages it will be intending to send. In those cases, you would probably be casting the object in order to pass it along, which is probably a clue that you should check to see if it really isKindOfClass: before you cast it.
Another thing to consider is ambiguity; respondsToSelector: tells you an object will respond to a message, but it could generate a false positive if the object returns a different type than you expect. For example, an object that declares a method:
- (int)sources;
Would pass the respondsToSelector: test but then generate an exception when you try to use its return value in a for-in loop.
How likely is that to happen? It depends on your code, how large your project is, how many people are writing code against your API, etc.
It's slightly more idiomatic Objective C to use respondsToSelector:. Objective C is highly dynamic, so your design time assumptions about class structure may not necessarily hold water at run time. respondsToSelector: gets round that by giving you a shortcut to the most common reason for querying the type of a class - whether it performs some operation.
In general where there's ambiguity around a couple of equally appealing choices, go for readability. In this case that means thinking about intent. Do you care if it's specifically a WidgetWithSources, or do you really just care that it has a sources selector? If it's the latter, then use respondsToSelector:. If the former, and it may well be in some cases, then use isKindOfClass. Readability, in this case, means that you're not asking the reader to make the connection between type equivalence of WidgetWithSources and the need to call sources. respondsToSelector: makes that connection for the reader, letting them know what you actually intended. It's a small act of kindness towards your fellow programmer.
Edit: #benzado's answer is nicely congruent.
Good answers from #Tim & #benzado, here is a variation on the theme, the previously covered two cases first:
If at some point you have may have a reference to distinct classes and need them differently then this is probably a case for isKindOfClass: For example, an color might be stored in preferences as either an NSData serialization on an NSColor, or as an NSString value with one of the standard names; to obtain the NSColor value in this case isKindOfClass: on the object return is probably appropriate.
If you have a reference to a single class but different versions of it over time have supported different methods then consider respondsToSelector: For example, many framework classes add new methods in later versions of the OS and Apple's standard recommendation is to check for these methods using respondsToSelector: (and not an OS version check).
If you have a reference to distinct classes and you are testing if they adhere to some informal protocol then:
If this is code you control you can switch to a formal protocol and then use conformsToProtocol: as your test. This has the advantage of testing for type and not just name; otherwise
If this is code you do not control then use respondsToSelector:, but we aware that this is only testing that a method with the same name exists, not that it takes the same types of arguments.
Checking either might be a warning that you are about to make a hackish solution. The widget already knows his class and his selectors.
So a third option might be to consider refactoring. Moving this logic to a [widget tryToRefresh] may be cleaner and allow future widgets to implement additional behind the scenes logic.

Imutability in Objective-c

I'm beginning an objective-c project. I have a question regarding immutability. Is it worth trying to make objects immutable whenever I can? If I update a field, I have to return a pointer to a new object and dealloc the old. If I do this often, there might be performance issues. Also, the code will probably be more verbose. There are undoubtedly other considerations. What do you think?
Edit: Let me clarify what I mean when I write "update a field". Normally, when you update a field you call a setter and just change the value of the field. If the object is immutable, the setter does not actually update the field, instead it creates a new instance, with all the fields having the same value, except for the field you are trying to update. In java:
class User{
private String firstName;
private String lastName;
public User(String fn, String ln){ firstName = fn; lastName = ln; }
public User setFirstName(String fn){ return new User(fn, lastName); }
}
Use immutable objects whenever possible, due to the performance overhead of mutable objects.
Edit: Well, usually the above should be true, but it seems there are situations where NSMutableArray performance is actually better then NSArray. Read some more about it on the Cocos2d site:
Read some more about mutability on CocoaWithLove (great weblog for Mac / iOS developers so put it in your favorites!).
I'd also like to add that a lot of objects have the -mutableCopy instance method, this is an easy to use method to retrieve a mutable copy from an immutable objects, like a NSArray or NSString, e.g.:
NSArray *array = [NSArray arrayWithObjects:#"apple", #"pear", #"lemon"];
NSMutableArray *mutableArray = [array mutableCopy];
// remember to release the mutableArray at some point
// because we've created a copy ...
Just remember in some situations a mutable object is easier to use, for example for a UITableView that makes use of a datasource that is subject to a lot of changes over time.
Whether mutable or immutable objects are best is very situation dependent, so it's best if you give a more concrete example to discuss. But here are some things to think about.
Often object properties are somehow inter-related. For instance, a Person might have a givenName and surname, but might also have a fullName that combines those two, and it might have a nameOrder that indicates which comes first. If you make Person mutable, then there can be points in time that fullName might be incorrect because you have changed the surname but not the givenName (perhaps one of them is still nil). You now need a more complex interface to protect you against this.
If other objects use this mutable Person, they have to employ KVO or notifications to find out when it has changed. The fact that interrelated fields might change independently can make this complex, and you find yourself writing code to coalesce the changes.
If some combinations of properties are illegal, mutable objects can be very hard to error check. An immutable object can do all of its checking when it is constructed.
There are some middle-grounds between mutable and immutable. In the above example of Person and various name properties, one way to simplify much of it is to let Person be mutable, but create a separate immutable Name object that contains the various parts. That way you can make sure that the entire name is mutated in an atomic way.
Immutable objects greatly simplify multi-threaded code. Mutable objects require a lot more locking and synchronization, and this can significantly hurt performance and stability. It's very easy to screw this code up. Immutable objects in comparison are trivial.
To your point about creating and throwing away objects, immutable objects also give the opportunity for sharing, which can make them very efficient if there are likely to be many objects pointing to the same data contents. For instance, in our Person example, if I make an immutable Address object, then every person who lives at the same address can share the same object. If one changes their address, this doesn't impact all the others.
As an example of the above, my code has a lot of email addresses in it. It's extremely common for the same string to show up over and over again. Making EmailAddress immutable, and only allowing it to be constructed with +emailAddressForString: allows the class to maintain a cache and this can save significant memory and time to construct and destroy string objects. But this only works because EmailAddress is immutable.
Anyway, my experience is that it's often better to err towards immutable data objects for simplicity, and only make the mutable when immutability creates a performance problem. (Of course this only applies to data objects. Stateful objects are a different thing, and of course need to be mutable by their nature, but that doesn't mean that every part of them must be mutable.)
As in any other imperative language: it depends. I've seen decent boosts in code performance when we use immutable objects, but they're also usually infrequently-modified objects, ones which are read out of an archive or set by a user and then passed around to all different bits of code. It doesn't seem worth doing this for all your code, at least not to me, unless you plan on heavily leveraging multiprocessing and understand the tradeoffs you're making.
I think the bigger immutability concern is that if you've done good design to keep your data marked immutable when it is such, and mutable when it is such, then it's going to be a lot easier to take advantage of things like Grand Central Dispatch and other parallelization where you could realize far greater potential gains.
As a side note, moving to Objective C from Java, the first tip I can give you is to ditch the notion of public and private.

iPhone, is using isKindOfClass considered bad practice in any way?

For example if there is a 'handle all' type method...
if ([obj isKindOfClass:class1]) {
// ...
} else if ([obj isKindOfClass:class2]) {
// etc..
Is this bad practice? Is there a neater alternative or a better way to structure the code?
Are there disadvantages in tearms of runtime, readability, maintainability or anything?
Whenever something is considered good/bad practice, it is more or less subjective. When doing something is inherently right/wrong, it is more or less objective.
isKindOfClass: is a useful method to check class inheritance. It answers the only question, "is the object of a class which is (a subclass of) a given class?". It doesn't answer any other questions like "does this object implement that method in its own way?" or "can I use the object for X or Y?". If you use isKindOfClass: as intended, you won't have any problems. After all, in a dynamic typed language you ought to have tools to extract meta information about objects. isKindOfClass: is just one of the available tools.
The fact that certain objects may lie about their class should not really put you off. They just disguise themselves as objects of another class without breaking anything. And if that doesn't break anything, why should I care?
The main thing is that you should always remember to use the right tool for any given purpose. For example, isKindOfClass: is no substitute for respondsToSelector: or conformsToProtocol:.
Sort of. This question basically covers what you're asking: Is it safe to use isKindOfClass: against an NSString instance to determine type?
There are some caveats you need to bear in mind (see link above), but personally I think it's a fairly readable method. You just need to make sure what you're doing inside your conditional test is appropriate (the example Apple give is along the lines of "an object may say it's a kind of NSMutableArray, but you might not be able to mutate it").
I would consider the example you gave to be an anti-pattern, so yes, I would say it is harmful. Using isKindOf like that is defeating polymorphism and object orientation.
I would far prefer that you call:
[obj doTheThing];
and then implement doTheThing differently in your subclasses.
If obj could belong to classes that you don't have control over, use categories to add your doTheThing method to them. If you need default behaviour, add a category on NSObject.
This is a cleaner solution in my opinion, and it helps to separate the logic (what you're doing) from the implementation details (how to do it for specific different types of object).

Why doesn't Objective-C support private methods?

I've seen a number of strategies for declaring semi-private methods in Objective-C, but there does not seem to be a way to make a truly private method. I accept that. But, why is this so? Every explanation I've essentially says, "you can't do it, but here's a close approximation."
There are a number of keywords applied to ivars (members) that control their scope, e.g. #private, #public, #protected. Why can't this be done for methods as well? It seems like something the runtime should be able to support. Is there an underlying philosophy I'm missing? Is this deliberate?
The answer is... well... simple. Simplicity and consistency, in fact.
Objective-C is purely dynamic at the moment of method dispatch. In particular, every method dispatch goes through the exact same dynamic method resolution point as every other method dispatch. At runtime, every method implementation has the exact same exposure and all of the APIs provided by the Objective-C runtime that work with methods and selectors work equally the same across all methods.
As many have answered (both here and in other questions), compile-time private methods are supported; if a class doesn't declare a method in its publicly available interface, then that method might as well not exist as far as your code is concerned. In other words, you can achieve all of the various combinations of visibility desired at compilation time by organizing your project appropriately.
There is little benefit to duplicating the same functionality into the runtime. It would add a tremendous amount of complexity and overhead. And even with all of that complexity, it still wouldn't prevent all but the most casual developer from executing your supposedly "private" methods.
EDIT: One of the assumptions I've
noticed is that private messages would
have to go through the runtime
resulting in a potentially large
overhead. Is this absolutely true?
Yes, it is. There's no reason to suppose that the implementor of a class would not want to use all of the Objective-C feature set in the implementation, and that means that dynamic dispatch must happen. However, there is no particular reason why private methods couldn't be dispatched by a special variant of objc_msgSend(), since the compiler would know that they were private; i.e. this could be achieved by adding a private-only method table to the Class structure.
There would be no way for a private
method to short-circuit this check or
skip the runtime?
It couldn't skip the runtime, but the runtime wouldn't necessarily have to do any checking for private methods.
That said, there's no reason that a third-party couldn't deliberately call objc_msgSendPrivate() on an object, outside of the implementation of that object, and some things (KVO, for example) would have to do that. In effect, it would just be a convention and little better in practice than prefixing private methods’ selectors or not mentioning them in the interface header.
To do so, though, would undermine the pure dynamic nature of the language. No longer would every method dispatch go through an identical dispatch mechanism. Instead, you would be left in a situation where most methods behave one way and a small handful are just different.
This extends beyond the runtime as there are many mechanisms in Cocoa built on top of the consistent dynamism of Objective-C. For example, both Key Value Coding and Key Value Observation would either have to be very heavily modified to support private methods — most likely by creating an exploitable loophole — or private methods would be incompatible.
The runtime could support it but the cost would be enormous. Every selector that is sent would need to be checked for whether it is private or public for that class, or each class would need to manage two separate dispatch tables. This isn't the same for instance variables because this level of protection is done at compile time.
Also, the runtime would need to verify that the sender of a private message is of the same class as the receiver. You could also bypass private methods; if the class used instanceMethodForSelector:, it could give the returned IMP to any other class for them to invoke the private method directly.
Private methods could not bypass the message dispatch. Consider the following scenario:
A class AllPublic has a public instance method doSomething
Another class HasPrivate has a private instance method also called doSomething
You create an array containing any number of instances of both AllPublic and HasPrivate
You have the following loop:
for (id anObject in myArray)
[anObject doSomething];
If you ran that loop from within AllPublic, the runtime would have to stop you sending doSomething on the HasPrivate instances, however this loop would be usable if it was inside the HasPrivate class.
The answers posted thus far do a good job of answering the question from a philosophical perspective, so I'm going to posit a more pragmatic reason: what would be gained by changing the semantics of the language? It's simple enough to effectively "hide" private methods. By way of example, imagine you have a class declared in a header file, like so:
#interface MyObject : NSObject {}
- (void) doSomething;
#end
If you have a need for "private" methods, you can also put this in the implementation file:
#interface MyObject (Private)
- (void) doSomeHelperThing;
#end
#implementation MyObject
- (void) doSomething
{
// Do some stuff
[self doSomeHelperThing];
// Do some other stuff;
}
- (void) doSomeHelperThing
{
// Do some helper stuff
}
#end
Sure, it's not quite the same as C++/Java private methods, but it's effectively close enough, so why alter the semantics of the language, as well as the compiler, runtime, etc., to add a feature that's already emulated in an acceptable way? As noted in other answers, the message-passing semantics -- and their reliance on runtime reflection -- would make handling "private" messages non-trivial.
The easiest solution is just to declare some static C functions in your Objective-C classes. These only have file scope as per the C rules for the static keyword and because of that they can only be used by methods in that class.
No fuss at all.
Yes, it can be done without affecting the runtime by utilizing a technique already employed by the compiler(s) for handling C++: name-mangling.
It hasn't been done because it hasn't been established that it would solve some considerable difficulty in the coding problem space that other techniques (e.g., prefixing or underscoring) are able to circumvent sufficiently. IOW, you need more pain to overcome ingrained habits.
You could contribute patches to clang or gcc that add private methods to the syntax and generated mangled names that it alone recognized during compilation (and promptly forgot). Then others in the Objective-C community would be able to determine whether it was actually worthwhile or not. It's likely to be faster that way than trying to convince the developers.
Essentially, it has to do with Objective-C's message-passing form of method calls. Any message can be sent to any object, and the object chooses how to respond to the message. Normally it will respond by executing the method named after the message, but it could respond in a number of other ways too. This doesn't make private methods completely impossible — Ruby does it with a similar message-passing system — but it does make them somewhat awkward.
Even Ruby's implementation of private methods is a bit confusing to people because of the strangeness (you can send the object any message you like, except for the ones on this list!). Essentially, Ruby makes it work by forbidding private methods to be called with an explicit receiver. In Objective-C it would require even more work since Objective-C doesn't have that option.
It's an issue with the runtime environment of Objective-C. While C/C++ compiles down into unreadable machine code, Objective-C still maintains some human-readable attributes like method names as strings. This gives Objective-C the ability to perform reflective features.
EDIT: Being a reflective language without strict private methods makes Objective-C more "pythonic" in that you trust other people that use your code rather than restrict what methods they can call. Using naming conventions like double underscores is meant to hide your code from a casual client coder, but won't stop coders needing to do more serious work.
There are two answers depending on the interpretation of the question.
The first is by hiding the method implementation from the interface. This is used, typically with a category with no name (e.g. #interface Foo()). This permits the object to send those messages but not others - though one might still override accidentally (or otherwise).
The second answer, on the assumption that this is about performance and inlining, is made possible but as a local C function instead. If you wanted a ‘private foo(NSString *arg)‘ method, you would do void MyClass_foo(MyClass *self, NSString *arg) and call it as a C function like MyClass_foo(self,arg). The syntax is different, but it acts with the sane kind of performance characteristics of C++'s private methods.
Although this answers the question, I should point out that the no-name category is by far the more common Objective-C way of doing this.
Objective-C doesn't support private methods because it doesn't need them.
In C++, every method must be visible in the declaration of the class. You can't have methods that someone including the header file cannot see. So if you want methods that code outside your implementation shouldn't use, you have no choice, the compiler must give you some tool so you can tell it that the method must not be used, that is the "private" keyword.
In Objective-C, you can have methods that are not in the header file. So you achieve the same purpose very easily by not adding the method to the header file. There's no need for private methods. Objective-C also has the advantage that you don't need to recompile every user of a class because you changed private methods.
For instance variables, that you used to have to declare in the header file (not anymore), #private, #public and #protected are available.
A missing answer here is: because private methods are a bad idea from an evolvability point of view. It might seem a good idea to make a method private when writing it, but it is a form of early binding. The context might change, and a later user might want to use a different implementation. A bit provocative: "Agile developers don't use private methods"
In a way, just like Smalltalk, Objective-C is for grown-up programmers. We value knowing what the original developer assumed the interface should be, and take the responsibility to deal with the consequences if we need to change implementation. So yes, it is philosophy, not implementation.