Building self contained classes - iphone

I have a bunch of classes that are used by a lot of my projects. Some of these classes have to access some other special classes that I have created. Because I want to make the classes as much independent of others I do not want to have #import lines to cross import classes that do not belong together. I would like to access information on those classes without having to use #import lines.
Apple has some special stuff that can be accessed without importing anything. For example:
[[UIApplication sharedApplication] delegate]
or
[[UIScreen mainScreen] bounds]
how do I create classes like that. Classes that I can simply do a
[[MyClass sharedClass] property]
or
[[MyClass sharedClass] runThis]
and have access to it. Without having any #import line.
Attention because I am not talking about a regular singleton. A singleton you have to still import its file.
Is this possible?

The reason why you don't see an import for those classes is because you have the UIKit framework as a part of your project, which is effectively importing those classes' .h files into every class you create. It is possible to do what you are describing, however, in terms of separation, by taking advantage of dynamic dispatch and dynamic typing in objective-c, however you will lose compile-time error checking.
For example, I have a subclass of UIApplication delegate with an NSManagedInstance property by the name "managedObjectInstance. I do not import this subclass's .h file, but instead use the valueForKey: method like so:
[((NSObject*)[UIApplication sharedApplication].delegate) valueForKey: #"managedObjectContext"];
The NSObject cast is just because the delegate property of sharedApplication is an id, which means that it doesn't necessarily conform to KVO. To call a method that you know exists on a class without provoking a warning, you can use the performSelector: family of functions like so
[objectOfSomeClassWeDidntImport performSelector: #selector(amethodWeKnowExists)]

You can do it....
Just make your imports in projectName-Prefix.pch file
and use the content of imported file wherever you want.
You can find .pch file in Resources folder.

Related

category with no name in the class's .m file

what does it mean to create a category like this: #interface myClass () ... #end in the same class's .m file ? this category may contain methods and properties, why not to add these methods and properties directly in the class's .h file ?
thank you in advance.
It's basically a workaround for Objective-C's lack of private methods. You put classes in there to hide them from users of the class. They can technically still use them (although they'll get a warning) but if they don't know about them, they probably won't.
Sometimes i would do this when i had a private method.
Because,if the method not define in header,when you call it in implementation,you got a warning, (your method's code is above your invoked).
like this:Instance method '-XXX' not found (return type defaults to 'id')
So,for no warning,i put a method define in a category maybe i will write a #interface myClass(private).
If there is no name in the parenthesis it is a class extension. If you define a name then it is a category.
The most common reason to do this is to hide instance variables and methods. To make the appear to be private.

Objective-C: Is a class just a .m and .h file?

I'm still coming to terms with classes and objects in Objective-C.
Is a class simply the combination of an interface and implementation file? Or, to put it another way, when would you say to yourself "I need a new .m file for this". At the moment I make a new implementation file when I want to put certain methods and variables in a separate place so that my main code doesn't become massive.
Any help would be greatly appreciated.
Strictly by convention and not by necessity, every new class should have an interface file (.h file) and an implementation file (.m file).
As far as using new .m files for distributing your methods, this is fine.
While convention dictates a pair of .h and .m files per class, the former containing the #interface and the latter containing the #implementation, there is no such requirement and, in fact, many of the system provided classes are divided across several files both in interface and implementation.
Technically, you don't need an #interface at all.
The absolute minimal class definition is:
#implementation Foo
#end
In that the above defines a class Foo that is a new root class. However, the compiler will warn about this.
Effectively, the minimal class definition is:
#interface Foo:NSObject
#end
#implementation Foo
#end
Note that NSObject is intentional; if you are going to make a class that will be compatible with the system frameworks or, even, the system runtime, inheriting from NSObject is pretty much required.
Syntactically, it is up to you as to how you separate the #interface and the #implementation. Traditionally, the interface goes in a header file such that others might #import it and use it while the implementation goes into a compilation unit -- a .m file -- to be compiled and linked exactly once.
But that is convention, not requirement. I've often defined a class --- #interface + #implementation -- entirely in a single .m file solely for use within the #implementation of some other class; effectively, a private class.
Note that class extensions -- #interface Foo() -- were expressly created to allow you to declare additional properties and methods on a class outside of the .h file's #interface Foo:NSObject. It allows a class to effectively have hidden API or to create a property that is publicly readonly and privately read-write.
No it's not. You can place multiple classes in a .h and .m file, althought this isn't deemed good practice.
In Objective-C classes are a pair of interfaces and implementations. These don't have to be in separate files but often are and it is a good way to keep your file structure clean. Often classes represent a little factory and when you have a group of functions that can be grouped together it is a good idea to put them in a class together.
I'll admit to occasionally grouping a few classes together, either with the definitions of all in one .h and the implementations in one .m, or, where some classes are "private", with the definitions AND implementations of "inner" classes in the .m of the major class.
I think it's sometimes good to avoid a proliferation of files this way, and to group interdependent classes together.
You can also go the other way -- spread the definition and and/or implementation of a class among multiple files using "categories" -- but that's a touch ugly and should generally be reserved for extending frameworks classes with specialized functions. (And even at that, done with some apprehension.)

How to set up non-instantiated classes in Objective-C (Classes with just methods)

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

Extending a class using categories with identical methods name

I want to extend a class using category NSArray+Populate.h:
#interface NSArray (Populate)
-(NSArray *) populateArray;
#end
How can I detect the situation if there is another category (from another module or library), extending NSArray with method having the same name ?
For example, if there is a NSArray+Fill.h:
#interface NSArray (Fill)
-(NSArray *) populateArray;
#end
As I understand, the run-time engine will choose one of the version silently, without any crash ?
You cannot detect this situation and you cannot determine which implementation of -populateArray takes precedence. Some developers prefer to prefix their category method names for this reason.
Quoting The Objective-C Programming Language document,
A category cannot reliably override methods declared in another category of the same class.
This issue is of particular significance since many of the Cocoa classes are implemented using categories. A framework-defined method you try to override may itself have been implemented in a category, and so which implementation takes precedence is not defined.

Can you access application delegate from within a UITableViewDataSource function?

I'm trying to figure out the SQLite functionality for the iPhone, and I'm having some problems reading my database file from an overridden UITableViewDataSource function. I am storing the database file location in an ivar (as an NSString) in my application delegate, however when I try to access that string from an overridden UITableViewDataSource function, it returns some other object. If I access the string from any of the classes own instance methods, it works fine.
Is there any way to access the application delegate from within overridden UITableViewDataSource functions?
The Application is a singleton which maintains a reference to the app delegate. You can always access your app delegate using:
[UIApplication sharedApplication].delegate
You may need to cast the return to your own app delegate class to get rid of warnings. Even better, write an accessor that returns your upcast app delegate:
#pragma mark access to app delegate etc.
+ (MyAppDelegateClass*) sharedAppDelegate; {
return (MyAppDelegateClass*)[[UIApplication sharedApplication] delegate];
}
Roger is correct, but I personally find it extremely confusing to mix dot syntax and bracket syntax in the same statement.
If this confuses you as well, the equivalent syntax, using only bracket notation, is:
[[UIApplication sharedApplication] delegate];
and yes, you may need to cast the result to be your application delegate class, rather than the generic UIApplicationDelegate class, or you will get a number of compiler warnings, most likely.
While I don't like sticking too much into my AppDelegate, I'll often need to access it to get to other singletons in my app, which makes the method call + cast a little cumbersome. So in most of my apps, I'll define a quick macro in my global header file.
Example follows:
#define MY_DELEGATE (AppDelegate*)[[UIApplication sharedApplication] delegate]
It's a lot easier to refer to MY_DELEGATE.
The problem turned out to be really simple. I had created the NSString to hold the path to my database file using stringByAppendingPathComponent: . I failed to realize that this was going to be autoreleased, and so I didn't bother to explicitly retain it. That reason it was returning a different type of object was because that memory had been reused once the string had been autoreleased.
Explicitly retaining the string holding the path to the database file solved the problem.