AbstractFactory pattern in objective-c - objective-c

I'm just trying to learn objectives-c.
I've seen wikipedia example for AbstractFactory pattern, across different languages.
Here's the Button definition:
#protocol Button
- (void)paint;
#end
#interface WinButton : NSObject <Button>
#end
Here's a factory:
#implementation WinFactory
- (id)createButton {
return [[[WinButton alloc] init] autorelease];
}
#end
As far as I kwnow, obj-c's id keyword should be something like C#'s var or C++11's auto,
right?
So I my question is:
why let the factory return a generic object of a not specified type?
Is this an error (that let factory return something other that is not a Button) or is there any reason to do that?
I'd write a factory this way:
#implementation WinFactory
- (id<Button>)createButton {
return [[[WinButton alloc] init] autorelease];
}
#end
am I wrong?

why let the factory return a generic object of a not specified type?
In many cases where you see id returned, it is because they are not consistently typed (really abstract objects), or it is because an implicit upcast would have been introduced.
Is this an error (that let factory return something other that is not a Button) or is there any reason to do that?
It is not an error. Of course, you should not return a type which does not match.
I'd write a factory this way:… am I wrong?
#implementation WinFactory
- (id<Button>)createButton {
return [[[WinButton alloc] init] autorelease];
}
#end
The big gotcha in this scenario is that ObjC is quite loosely typed, and you should strive to ensure all selectors' parameters and return types match. That is to say, every createButton in all your translations should all return the same type and have the same types for parameters. Sometimes you will have to choose a more descriptive name in order to avoid ambiguity for the compiler.
That ought to explain why +[NSString string] returns id -- if it returned NSString, then +[NSMutableString string] could be a source of warnings. This is because the compiler can have a difficult (impossible) time matching a method declaration to a dynamic instance. That may also help you understand the 'wordy' naming of selectors, such as convenience constructors which also contain the type in the method (e.g. +[NSDictionary dictionaryWithObject:] as opposed to simply +[NSDictionary withObject:]).
But to get to your question: id<Button> or NSObject<Button>* or some other qualified type is just fine -- as long as you can live with that common method signature. You're introducing type-qualification, which helps the compiler help you.

The more correct return type here would be :
- (id<Button>)createButton;
This means that the returned type is an object that conforms to the <Button> protocol. I may fix up the WP page just to be a little more clear. The <Button> protocol should also inherit from the <NSObject> protocol for completeness (and to simplify actual usage).
Note that the Abstract Factory pattern is somewhat unusual in ObjC. I'm trying to think of a case where it's used in UIKit or Foundation. It's more common for the class to handle this internally (such as in NSNumber) and is called a class cluster.
Be very careful of trying to code in a C++ or C# style in ObjC. ObjC is not a static language, and the patterns used are often quite different. (I'm not saying that AF is a static pattern. It could be used quite well in ObjC. I'm just saying that the fact that you're looking at it while trying to learn ObjC means that you may be approaching it backwards, learning "how do I do this C++ in ObjC" rather than learning "how do I develop in ObjC.")

Objective-C has the concept of class clusters, which are abstract factories.
See this answer.

Related

Inline accessor (getter/setter) methods in Objective-C

Data encapsulation, or as I like to call it, Who owns it and who needs to know about it, makes up a lot of object-oriented programming. The who needs to know is often satisfied by accessor methods, but these get to be pretty expensive if they all result in an objc_msgsend just to read a variable. C++ answers the problem with inline methods - use the "inline" keyword before the definition, or define the method within the class declaration, and the compiler puts the accessor code within the caller's code, saving the overhead associated with an actual function call.
class IntWrapper {
public:
int getInt() { return anInt; }
protected:
int anInt;
};
Similar syntax is rewarded by a complier error in Objective-C. Having searched the language guides in Xcode ("[Object-Oriented] Programming with Objective-C"), I don't see any relevant reference to "inline" of a method. Is there such thing as inline in Objective-C? Is it called something else? If anyone could point me to the documentation that references inline, much appreciated.
Using the simple test code:
#interface ClassA : NSObject
{
int anInt;
}
- (int) anInt;
#end
#implementation ClassA
- (int) anInt { return anInt; }
#end
and looking at the assembly of the code that uses it, it looks like about 25 instructions.
All Objective-C methods are dispatched dynamically. They can be overridden by subclasses. They can even be replaced at runtime ("swizzled") by the Objective-C runtime API.
In some ways, they are similar to virtual methods in C++.
As such they can't be inlined.
By the way, the technique you cite violates the principle you cite ("Who owns it and who needs to know about it?"). Putting the implementation in the class declaration exposes implementation detail to clients who don't need to know it. Furthermore, the compiler inlining the code into clients prevents that implementation from changing without a recompile, which is the fragile base class problem. Modern Objective-C avoids the fragile base class problem, which means a framework class can change what instance variables it has without breaking clients.

Is it an acceptable pattern for an init method to return an object of a different type?

I'm working on bugfixes for some existing objective-c code and came across something I thought strange:
#interface ClassA : UIView
...
static ClassA* oldSelf = nil;
#implementation
- (id)initWithFrame:(CGRect)frame {
oldSelf = self;
self = [[ClassB alloc] initWithFrame:(CGRect)frame]; // xcode warns: Incompatible pointer types assigning to "ClassA *" from "ClassB *"
// ^^^^^^ Is this ok?
[oldSelf release];
return self;
}
#interface ClassB : UIView
...
#implementation
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
return self;
}
This whole thing is wrapped up into a static library. The public gets the lib.a file and ClassA.h
In code using the library, This occurs:
#import "ClassA.h"
...
// useage
ClassA *myA = [[ClassA alloc] initiWithFrame:CGRectMake(0,0,100,100)];
...
So we got an initializer for ClassA that actually returns an unrelated class. ClassA and ClassB respond to the same messages so it compiles and runs. Seems like ClassA is being used to obscure some features exposed in ClassB?
I'm curious if this is acceptable behavior, and if it's a known pattern, what is it called? Are there any side effects to this setup?
=========================================================
Thanks for everyone's answers! I think I've got it... in short, not a normal pattern, and not exactly a good idea
Kind of like a "class cluster"(abstract factory), but not quite, because a common abstract class should be returned. And since the code doesn't seem to ever intend to return anything but a ClassB object, probably not what the original author was thinking.
More like a proxy, but implemented wrong. ClassA should hold a private instance of ClassB and pass messages between the two.
=========================================================
Edited: added "oldSelf" parts...
Edited: added static library details...
Edited: added a blurb about the accepted answer...
The major disadvantage I see here is: a user of ClassA would expect that an object he just created via [[ClassA alloc] initWithFrame:...] returns YES for [object isKindOfClass:[ClassA class].
This might also lead to errors when using things like NSInvocation, because the wrong class would be used to determine the method signature, though I am not sure about that.
Due to Objective-Cs dynamic nature, this will, as you described, work, but may be confusing to use and i would strongly discourage anyone from using this pattern.
As pilavdzice said, the "right" alternative to this would be to have both ClassAand ClassB inherit from another class (an abstact superclass) which then in its initializer decides what concrete subclass to use. Good examples of this pattern, called class clusters, are NSString, NSArray and NSDictionary which all return objects of various subclasses based on how you initialize them, which is also the reason you can not subclass those directly without some effort.
It's not an unreasonable thing to do in all cases, but it's hard to say whether it's a good idea in the situation you describe. Two examples where it might be fine:
The initializer returns an instance of a more specialized subclass. For example, you might choose different implementations of a data structure depending on the number of items being stored.
The initializer returns some sort of proxy object.
Your code does seem a bit odd. At the very least, I'd expect to see a cast as a signal (both to the compiler and to future programmers) that the author knew what he was doing. A comment explaining the reason for returning a different type of object wouldn't hurt, either. Ideally, ClassB should be a subclass of ClassA since it's expected to provide the same interface.
Class clusters are implemented in this way, sort-of. A related technique, isa-swizzling can be used to implement a sort of state machine. It does require the same ivar layout to work. In terms of side effects, I believe that it may break KVO; but someone may correct me on that point.
It's certainly not common in user code to return an unrelated class, however it is common in some of Apple's frameworks to return a more specific version of a class with the same public interface.
Apple's Cocoa Fundamentals discusses in some amount of detail the fact that objects such as NSArray and NSNumber may return a different object than the class you are asking for.
That isn't a pattern I know of.
If I am understanding this correctly, the normal way to do this would be to have both classes inherit from the same abstract base class.
As #alan duncun notes, this technique is called a class cluster and is somewhat common. But your implementation is slightly incorrect. You should never return a incompatible type. In your example, ClassB should inherit from ClassA.
Well this is somewhat how NSScanner is implemented.
This way the inner class is not exposed and can not be misused. ClassB can not be initialized somewhere else other than in the implementation file of ClassA.
This makes sense if you have multiple inner classes and your initializer somehow decides which class is actually needed.
I don't see any advantages if you only use one inner class.

dynamic properties in objective c

I found out Objective-C object properties can be marked as #dynamic to let compiler know that implementation will be available at runtime. I'd like to know if there is a way to tell the compiler that all properties on an object are dynamic without explicitly specifying them one-by-one (I don't have a list of properties up front). I know that this would not be a problem if I would just use [object something] but for stylistic purposes I want to use object.something syntax.
I'm fairly sure that it's not possible to do that but I'd like someone to confirm that. Since this is not for production use solution can involve anything you can imagine.
Thanks.
Additional info:
I only care about -something (getter) working so if your solution does not support setters that is fine.
Example:
#interface MagicalClass : NSObject
// property 'something' is not defined!
#end
#implementation MagicalClass
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { ... }
- (void)forwardInvocation:(NSInvocation *)anInvocation { ... }
#end
MagicalClass *obj = [[MagicalClass alloc] init];
[obj something]; // compiler warning
obj.something; // compiler error
This really doesn't work with declared properties. The whole point of them is that you declare upfront what your properties are and how you interact with them. If you don't have any to declare, then you don't have any declared properties.
Unfortunately, it also doesn't work well with plain messages, although it can work better than dot syntax. Objective-C's static type checking will throw a hissy-fit of warnings, and if any of the properties are of non-object types, it might not be able to generate the correct calling code.
This kind of thing is common in languages like Python and Ruby where things don't have to be declared, but it just doesn't mesh well with Objective-C. In Objective-C, accessing arbitrary attributes is generally done with strings (cf. Key-Value Coding and NSAttributedString).
I don't believe this is possible. If you use the id type, you may be able to send undeclared messages, but dot syntax really relies on knowing about your specific accessors.
I haven't tried this, but if you provide a getter and setter, does Xcode still want the #synthesize or #dynamic directive?
So if you property is called something, implement -setSomething: and -something.

Dynamic Getters and Setters with Objective C

I am in a situation where I want to dynamically generate getters and setters for a class at runtime (in a similar manner to what NSManagedObject does behind the scenes). From my understanding, this is possible using resolveInstanceMethod: on a specific class. At this point, you would have to use class_addMethod to dynamically add the method based on the selector. I understand this at a theoretical level, but I haven't delved much into the obj-c runtime, so I was curious if there were any great examples of how to do this. Most of my knowledge comes from this article:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtDynamicResolution.html
Any thoughts / examples?
The only nice discussion I know is at Mike Ash's blog post. It's not that hard, actually.
I once needed to split a big NSManagedObject subclass into two, but decided to keep the fact an implementation detail so that I don't have to rewrite other parts of my app. So, I needed to synthesize getter and setter which sends [self foo] to [self.data foo], automatically.
To achieve that, I did the following:
Prepare the new method, already in my class.
- (id)_getter_
{
return objc_msgSend(self.data, _cmd);
}
- (void)_setter_:(id)value
{
objc_msgSend(self.data, _cmd,value);
}
Note that _cmd has the selector in it. So, usually, _cmd is either #selector(_getter_) or #selector(_setter_) in these methods, but I'm going to plug the implementation of _getter_ as the implementation of foo. Then, _cmd contains #selector(foo), and thus calls self.data's foo.
Write a generic synthesizing method:
+(void)synthesizeForwarder:(NSString*)getterName
{
NSString*setterName=[NSString stringWithFormat:#"set%#%#:",
[[getterName substringToIndex:1] uppercaseString],[getterName substringFromIndex:1]];
Method getter=class_getInstanceMethod(self, #selector(_getter_));
class_addMethod(self, NSSelectorFromString(getterName),
method_getImplementation(getter), method_getTypeEncoding(getter));
Method setter=class_getInstanceMethod(self, #selector(_setter_:));
class_addMethod(self, NSSelectorFromString(setterName),
method_getImplementation(setter), method_getTypeEncoding(setter));
}
Note that this is a class method. So self stands for the class. Note also that I didn't hardcode type encodings (which tells Objective-C runtime what the arguments of the particular method are). The syntax of type encodings is documented, but constructing by hand is very error-prone; I wasted a few days that way until Mike Ash told me to stop it. Generate it using an existing method.
Generate forwarders at the earliest possible time:
+(void)load
{
for(NSString*selectorName in [NSArray arrayWithObjects:#"foo", #"bar", #"baz",nil]){
[self synthesizeForwarder:selectorName];
}
}
This generates foo, setFoo:, bar, setBar:, and baz, setBaz:.
Hope this helps!
Another example is one I wrote, called DynamicStorage, available here:
https://github.com/davedelong/Demos
The primary impetus behind it was this question, which was asking how to use an NSMutableDictionary as the backing store for any object ivar. I wrote a class that will generate getters and setters for any #property, respecting things like a custom getter/setter name, the object memory management policy, etc. The neat thing about it is that it's using imp_implementationWithBlock() so that it only has to calculate the appropriate property name once (and then captures and saves it as part of the block).

Method Overloading in Objective-C - not used for init?

I have just started programming in Objective-C, I understand it only partially supports method overloading due to the way the method names are generated (see this question).
However, my question is why I have never seen it used in any examples. The code below seems to work fine, but any sort of example I have seen, the second init would be named initWithServerName or something like that, instead of taking advantage of the overloading.
-(id) init {
self = [super init];
return self;
}
// usually this would be called initWithName or something? but to me it
// seems easier this way because it reminds me of method overloading from C#.
-(id) init: (NSString*)newServerName {
self = [super init];
if(self) {
serverName = [[NSString alloc] initWithString:newServerName];
}
return self;
}
What is the reason for this? Does it cause problems in sub-classes to name methods this way?
Unlike Algol-style languages like C#, Objective-C's syntax is specifically designed for literate method names. init: tells me nothing about the method parameter. Is the receiver initing the thing I'm passing? No. It's using the argument in some way, so we use a descriptive name like initWithFormat: to specify that the argument is a format string.
Also, Objective-C does not have method overloading at all. Period. A single selector for a given class can only have one type signature. The only way to change behavior based on an argument's class is to have a method take a generic type that could include many different classes (like id or NSObject*), ask the argument for its class and do different things depending on the result of that query.
That's not the same method. In objective-C a selector named init is different than one named init:. The colon is part of the selector name.
Also, init is overridden fairly often, you just have the wrong method.
Aside from jer's answer, it also does not allow you to specify multiple ways to initialise an instance. For example, NSString has initWithString:, initWithFormat:, etc.