I'm familiar (or at least getting familiar) with instance and class methods in objective-c, but have also seen method implementations that look like this:
#import "Utilities.h"
#import "CHAPPAppDelegate.h"
#import "AppState.h"
#implementation Utilities
CHAPPAppDelegate* GetAppDelegate() {
return (CHAPPAppDelegate *)[UIApplication sharedApplication].delegate;
}
AppState* GetAppState() {
return [GetAppDelegate() appState];
}
#end
What are these? While I'm sure this is documented somewhere, I don't know what term to use in searching for an explanation of what's being done here. I like the syntax methods like this let me use when calling them, but I'm not sure exactly what I'm doing, what the implications are, how to send parameters to these types of functions, etc?
These are c functions that wrap objective-c functions.
Those aren't methods at all. They are just functions, exactly like in normal C. They aren't part of the class. The body of the functions are written in Objective-C (i.e. the functions send messages to objects), but functions themselves are completely independent of objects and Objective-C.
Related
I'm looking to create a class in Objective-C for an iOS project that is focused on fetching data. I'm familiar with how classes normally work, setter and getter methods and variables. However, for this class since it's only performing a function (returning NSMutableArrays) I don't want to have to create an instance of the class to use the methods inside the class.
Any idea how I can do this neatly and efficiently?
This is a little bit atypical in Objective-C. Since classes in Objective-C can't actually have state beyond what is available to ordinary functions (i.e. there are no class variables), a class that's never instantiated is relatively useless in most cases. The normal design patterns for this kind of functionality are:
A singleton class (if you need lots of state)
A set of functions (if you don't)
You want to make class methods?
#interface Foo : NSObject {}
+(NSMutableArray*)someClassMethod:(id)params;
#end
...
#implementation Foo
+(NSMutableArray*)someClassMethod:(id)params {
// whatever implementation
return nil;
}
#end
...
NSMutableArray* array = [Foo someClassMethod:nil];
If you're only performing functions, and you don't need to support subclassing etc, why not just write them as C functions rather than a class with methods?
If this is just a class that performs some functions, you could write it as a C function.
In your header file --
NSMutableArray *functionThatReturnsMutableArray(NSObject *param1, NSString *param2);
In your implementation file --
NSMutableArray *functionThatReturnsMutableArray(NSObject *param1, NSString *param2)
{
...
return aMutableArray;
}
And that just include the .h file in your class that needs these functions and call them directly.
NSMutableArray *anArray = functionThatReturnsMutableArray(param1, param2);
Depending on what you are doing (the same NSString operations, UIView manipulations, etc), you could implement a category (I answered a question yesterday with the explanation below -- copied for your convenience ;).
Categories extend an existing class with additional methods or with your version of existing methods. For example, let's say you want to add a method that returns the first letter of a string to NSString. To do this you would create a category as follows:
Interface - JULString.h
#import NSString
#interface NSString (JULString)
-(NSString *) firstLetter;
#end
Implementation - The typical convention is that the filename of the category is the name of the class you are extending followed by “+” and the name of the category. In this case the file would be called NSString+JULString.m
#import "NSString+JULString.h"
#implementation NSString ( JULString )
- (NSString *)firstLetter
{
return [NSString stringWithFormat:#"%C", [self characterAtIndex:1]];
}
#end
The neat thing about categories is that now they extend the behavior of ANY instance of the class you are working with. In other words, any NSString in your application will have your new methods (provided that you import the proper header file of course). Beware though, as with great power comes great responsibility. Overwriting class using a category behaviors may lead to undesired effects, so be cautious.
A couple of links you may want to check are:
Apple's guide to Objective-C
Learn Objective-C
Note:
I don't have my Mac with me so I'm writing this code basically off the top of my head (and using some code from the sites above as a reminder). So I apologize in advance for any mistakes ;)
This may be a silly question but I haven't found any information on it.
Let's say several of the classes in my program derive from 'MySubView' which is derived from another class, UIViewController.
I would declare it like this:
#interface NewViewController : MySubView {
// code ...
}
#end
In the future the client wants a change, and desires another view with a table. So I would need to make another class, called MySubTableView, that is a UITableViewController subclassed from MySubView.
I was thinking this would be easier if I could do something like this:
#interface NewViewController : UITableViewController : MySubView {
// code ...
}
#end
But this doesn't work.
Is there a way to do this with Xcode, or do I have to specifically make the class itself?
EDIT:
I'm not looking for multiple inheritance. A straight inheritance hierarchy would follow:
NewViewController
UITableviewController
MySubView
UIViewController
No, Objective-C doesn't support declaring those kind of (vertical) inheritance chains. You can only specify the direct super class.
Even if it was possible, there would be problems like calling the correct initializers as they won't be called automatically. Consider a hierarchy like A : B : C - now you can initialize B using e.g. [super init] in As initializer, but how would B know what initializer you want it to call for C?
Objective-C doesn't support multiple inheritance... But Objective-C programmers rarely miss it, because you can accomplish many of the same tasks using Categories instead. Read up on Objective-C Categories.
Can a Objective c interface have more than one implementation? Example I could have a interface but 2 implementations one where i use an arrays or another where I use a stack..etc to implement it.
If so how do you call it / syntax?
Objective-C has the concept of a Protocol, which is the specification of an interface. Through Protocols, Objective-C fully supports multiple inheritance of specification (but not implementation). So, a bit confusingly, the #interface syntax actually defines the class (implementation), which only supports single inheritance, but can specify the implementation of many / multiple inheritance of Protocols, or specifications of interfaces. In the end, this is very similar in nature to Java.
For example:
#protocol SomeInterface
- (void)interfaceMethod1;
- (void)interfaceMethod2;
#end
#interface SomeClass:NSObject <SomeInterface>
#end
#interface AnotherClass:NSObject <SomeInterface>
#end
Instances of either SomeClass or AnotherClass both claim that they provide the implementation required for the SomeInterface protocol.
Objective-C is dynamically typed and doesn't require that the object actually specify the message being sent to it. In other words, you can indiscriminately call any method you would like on SomeClass, whether it is specified in it's interface or any of its protocols or not (not that this would necessarily be a productive or positive thing to do).
Therefore, all of the following would compile (although with warnings) and run fine, although the messages / methods without implementation is basically a no op in this case. Objective-C has a fairly complicated (and very cool) process of handling method calling / forwarding that is a bit beyond the scope of this question.
SomeClass * someObject = [[SomeClass alloc] init;
[someObject someUnspecifiedMethod]; // Compiles with warning - no op
[someObject interfaceMethod1];
If you wish to define something that can be any class (#interface) type but implements a specific interface (#protocol), you can use something like this:
id <SomeInterface> obj;
obj could hold either a SomeClass or AnotherClass object.
Perhaps you should try Cocoa pattern called Class Cluster. To start using it you need to create public class called SomeClass and two private subclasses SomeArrayClass and SomeStackClass. When you need to use stack your public class constructor will create instance of SomeStackClass and will return it as publicly available instance of SomeClass.
(If you give this a vote, please give Roman a vote -- his answer was first, is correct, just lacked an example).
You are talking about a Class Cluster. For an example, look at the NSString class.
There is NSString:
#interface NSString : NSObject
And NSMutableString:
#interface NSMutableString : NSString
Both of which declare an extremely small set of methods in the core class's declaration. If you were to subclass NSString to implement your own string class, you would only need to implement those core methods. All other methods implemented in NSString are implemented in terms of those core methods. And, likewise, the mutation methods are implemented using the primitive methods declared in the core of NSMutableString.
Now, obviously, implementing all mutability via - (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)aString (the one core method) would be grossly inefficient. Thus, at runtime, you'll note that you never actually have an instance of NSString or NSMutableString, but only instances of subclasses (which, actually, aren't really subclasses... but they might as well be in the context of this discussion).
And those subclasses -- the implementation class used at runtime -- overrides almost all of the methods of NSString and NSMutableString to provide highly optimized implementations of the specific operations.
So, you would do something like:
#interface MyAbstractClass : NSObject
... declare factory methods here ...
... declare core methods here ...
#end
#interface MyAbstractClass(AdditionalFunctionality)
... declare convenience here ...
#end
Then, in the implementation, implement all of the core methods as #throw #"Must use subclass" and all AdditionalFunctionality methods in terms of the core methods.
This could be entirely private -- not in a header at all, even:
#interface MyStackClass : MyAbstractClass
#end
#implementation MyStackClass
... implement the core methods and override the additionalfunctionality methods that need optimization ...
#end
Repeat for your additional types of classes. Then, implement factory methods on MyAbstractClass that return instances of the subclasses, as needed.
You mean for example like this:
#interface MasterViewController :
UIViewController <GKPeerPickerControllerDelegate,
GKSessionDelegate,
UITextFieldDelegate,
UITableViewDelegate,
AVAudioRecorderDelegate> {
}
In winforms/C# most all UI Controls have a .Tag tag, so like myButton.Tag = myObject; where the Tag property is an 'object' type so you can basically store any type of object. How might I accomplish this in Objective-C/Cocoa? do all UI elements have something like .Tag where I can store an NSObject or something? If so, can you please provide an example. Thanks so much!
Note: I did see the integer .Tag there, but I wanted an object tag. But I guess that doesn't exist. hoo well.
As Georg said, you can associate whatever object to another object using the Objective-C runtime, so you can associate an Object to a control if you really want.
But that is not really how a standard Cocoa program works. Instead, in Cocoa, the Model-View-Controller pattern and the Delegation are the standard idiom, and associating an object directly to a widget or a view is discouraged. Even for a very small program, you would at least create a Model-Controller (called usually the application delegate in the Cocoa jargon) which manages the data, and keep the view composed of the standard controls as is. Then the view and the model-controller interact via target/action and delegation.
Apple has a very nice discussion of design patterns prevalent in Cocoa, see here.
In general, when you move from one API(Winforms/C#) to another API(Cocoa/Objective-C), there are some similarities but also some differences. It is usually worth learning how things are done in that API, rather than trying to shoehorn what you're used to into a new situation. (Just to be clear, I'm not saying which API is inherently better; this discussion goes both ways!)
So, when you are in a situation:
To do X in API A, I know the idiom P works. I now want to do X in API B. How can I directly implement idiom P in API B?
I recommend you to ask
To do X in API B, what should I do? What's the idiom in API B?
instead.
NSControl does have a tag and related setTag: method. It's not used internally so you can store whatever you like in it - it only stores NSInteger values though.
All Cocoa controls inherit from NSControl.
There is the possibility to add a tag, it's an integer if I remember correctly.
This said, I'm pretty sure one never needs this functionality in Cocoa, because it just doesn't work this way.
If you really want to add information you might be interested in the runtime's ability to associate an object with another object.
CALayers have the ability to store arbitrary keys as part of their key-value coding machinery. Example:
CALayer *myLayer = [button layer];
// Storing a value
[layer setValue:#"World!" forKey:#"hello"];
// Retrieving a value
NSLog(#"Hello %#", [layer valueForKey:#"hello"]);
That being said, storing objects against user-interface elements violates the principle of the Model-View-Controller pattern; I would advise against it--a UIView or UIControl subclass would likely be better suited.
Yep. You can add your own property to all UIControls if you like.
Just add the following to your code.
#import <objc/runtime.h>
/* -------- The Following Code adds an objectData property for every UIControl ----------- */
#interface UIControl (UIControlAdditions)
#property (nonatomic, retain) id objectData;
#end
static char const * const ObjectDataKey = "MyObjectDataKey";
#implementation UIControl (UIControlAdditions)
#dynamic objectData;
-(id)objectData {
return objc_getAssociatedObject(self,ObjectDataKey);
}
- (void)setObjectData:(id)newObjectData {
objc_setAssociatedObject(self, ObjectDataKey, newObjectData, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
#end
/* -------- The Above Code adds an objectData property for every UIControl ----------- */
Credits to Ole Begemann: http://oleb.net/blog/2011/05/faking-ivars-in-objc-categories-with-associative-references/
I'm on a project doing an iPhone application. We had a Cocoa consultant come in for a few weeks. He showed me an interesting idiom of Cocoa, dealing with interfaces, but there was a difficult language barrier between us, and he wasn't really able to explain why this was done or where it was documented so I could learn more on my own. I went into monkey see mode, and just used the style he prefers. But it's been bugging the hell out of me that I don't know more about the history of this style. It's certainly NOT an informal protocol. Sure enough, looking at some of the Cocoa API headers, I sometimes see the style he asserted was the 'Cocoa' way. Here's an example (note accessors, mutators, etc., each have their own interface declaration without the funny braces):
#interface AViewController : UIViewController <UITextViewDelegate> {
#public
UITableView *tableView;
#private
NSUInteger someIndex;
}
#property (nonatomic, retain) ...
#end
#interface AViewController (AViewControllerCreation)
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil withController:(id)controller;
#end
#interface AViewController (AViewControllerMutator)
- (void) doSomeSettingStuff;
#end
#interface AViewController (AViewControllerAccessor)
- (NSString *)doSomeAccessorStuff;
#end
#interface AViewController (AViewControllerAction)
- (IBAction)cancel:(id)sender;
#end
#interface AViewController (AViewControllerTableViewDelegate) <UITableViewDelegate, UITableViewDataSource>
#end
You can see this style of setting up the interface in NSButton, NSControl, etc. Interestingly, corresponding classes like UIButton, UIControl DON'T use this idiom. Hmm, these probably came after as I assume UIKit was done after AppKit. So is this idiom 'old hat'? Also, is there any reason for it other then style? Is it good style? Bad? Any docs that go over this? Thanks all.
These are what's known in Objective-C as "categories". Categories make it possible to have multiple #interface and #implementation blocks for the same class. This works even to the extent that you can add methods on classes in the standard Apple frameworks, e.g. adding a category on NSString to add new methods to it. Categories can add methods but not instance variables, so in your example the first #interface is the core class declaration and all of the others are categories on the AViewController class.
It's not "old hat" by any means but your example takes the use of categories to a rather bizarre extreme. Categories make sense wherever it makes logical sense to break up a class's implementation into multiple blocks, for example if the class has a bunch of methods that logically fall into two or more groups. They're also sometimes used to declare pseudo-private methods by putting a category #interface named "private" in the same file as the #implementation. ObjC's dynamic dispatch means there's no such thing as a private method but this approach avoids publishing the names of methods you'd prefer people not to use.
The example above is not actually wrong but it's kind of ridiculous. It suggests that the contractor got the idea that every new method should always have its own category for some reason, which is just not true.
That example is very strange and would definitely raise a red flag for any experienced Cocoa programmer.
It is a common practice to use categories in the same way to separate private methods from the public implementation, and I've done the same thing in the past to separate private threaded methods from code that runs on the main thread. I can't see any good that would come from separating out all your public methods like that though.
What is a good tool for this situation is the #pragma mark <label> keyword. which allows you to group similar methods in an implementation. I think that's what you're aiming for, although you don't need to go overboard in creating groups. For example, in a window controller class I would have #pragma mark API, #pragma mark NSWindowController Overrides, #pragma mark NSObject Overrides, #pragma mark NSWindow Delegate Methods, and so on. That helps me find and jump to the method I'm looking for very quickly in Xcode, although it's just a matter of style so you can really use it however you see fit.
One really good reason for having a public category, and one that Apple uses often, is for extending a class with functionality that exists in the category's framework, but which doesn't exist in the framework that defines the class. For example, NSString is defined in Foundation.framework, but categories on NSString defining methods for drawing an NSString to the screen are defined in AppKit.framework.
Another good usage of categories is for dependency hiding; e g if you really need boost for a part of the class, you can have that in a separate header and implementation file, and a user of the class that needs the boost parts can import that header together with the one originally defining the class, and only that file will take ages to compile. This is more useful in the 64-bit runtime, where a category can add instance variables.
A really large implementation over several source files (but a single header) is also a good candidate, as Tom points out :)
I'd just like to add to Tom's original answer: Generally, it's better to use a class extension than a class category when declaring private methods. This way, you can implement the extension in the same #implementation block as the public methods, without getting a warning about "missing category implementation". Example:
// .h file
#interface Foo : NSObject
-(void)publicMethod;
#end
// .m file
#interface Foo ()
// Notice the empty paren; this is how you define
// a class extension, which is not the same as a category
-(void)somePrivateMethod;
#end
#implementation Foo
#pragma mark Public methods
-(void)publicMethod;
{ ... }
#pragma mark Private methods
-(void)privateMethod;
{ ... }
#end
I don't know; those look a lot like informal protocols to me, largely for delegates. See pages 297 - 298 of Cocoa Programming with Mac OS X, 3rd Edition. The protocols are implemented via Categories ... And in all honesty, they appear to be heavily overused in your sample.
Regarding John Rudy's response-- It's true that informal protocols are implemented as categories, but they're generally categories on NSObject. Since the informal protocol might be used by almost any object, it needs to be a category on an class that the adopting object inherits from, and pretty much everything is going to inherit from NSObject. You could make a case for an informal protocol as a category on some other class in specific situations, but it's an unusual approach and definitely not "the Cocoa way"
Ok, I believe Tom's answer is the most useful so far. However, as everyone seems to think this an overboard use of categories I again took a look at NSButton. Below is a bastardized version of the header:
#interface NSButton : NSControl <NSUserInterfaceValidations>
- (NSString *)title;
- (void)setTitle:(NSString *)aString;
...
...
#end
#interface NSButton(NSKeyboardUI)
- (void)setTitleWithMnemonic:(NSString *)stringWithAmpersand;
#end
#interface NSButton(NSButtonAttributedStringMethods)
- (NSAttributedString *)attributedTitle;
- (void)setAttributedTitle:(NSAttributedString *)aString;
- (NSAttributedString *)attributedAlternateTitle;
- (void)setAttributedAlternateTitle:(NSAttributedString *)obj;
#end
#interface NSButton(NSButtonBezelStyles)
- (void) setBezelStyle:(NSBezelStyle)bezelStyle;
- (NSBezelStyle)bezelStyle;
#end
#interface NSButton(NSButtonMixedState)
- (void)setAllowsMixedState:(BOOL)flag;
- (BOOL)allowsMixedState;
- (void)setNextState;
#end
#interface NSButton(NSButtonBorder)
- (void) setShowsBorderOnlyWhileMouseInside:(BOOL)show;
- (BOOL) showsBorderOnlyWhileMouseInside;
#end
#interface NSButton (NSButtonSoundExtensions)
- (void)setSound:(NSSound *)aSound;
- (NSSound *)sound;
#end
So if their using categories to organize NSButton into sections: (NSButtonMixedState) (NSButtonBorder) above, that really only have a couple of operations, why is using this for organizing accessors/mutators bad style? Of course my first example was a silly pedantic interface, but the intent of separating groupings of operations is the same.
First of all, just because something appears in one of Apple's header files doesn't necessarily mean you should take it as an example of a good way to do things. Apple's developers are human too, and subject to the same limitations of skill and time pressures as anyone else.
Using multiple categories in this way suggests that NSButton's implementation is divided into several source files. This might be because the different aspects of NSButton were coded by different people, or at different times, or possibly some other reason. Regardless the division is likely based in part on how the development team and its processes are organized, with the category system providing a way for the work to be divided. In the ideal setup you'd break things up on logical functional boundaries but in practice other factors can come into play.