Creating "Global Methods" [duplicate] - objective-c

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to create global functions in Objective-C
I am curious how it is commonly done to create global utility methods in Objective C that any Class can use.
The simple and only solution I can think of is to simply create a class, i.e. call it GlobalMethods, and just create a bunch of class methods so that they can be used without this class ever getting instantiated.
Is this a wise and valid approach? Regarding the type of methods, they might be anything, for example custom math formulas I use, etc.

There are a few common ways to make some code usable globally. Here are some, with examples from Apple's public APIs:
Create class methods on a new class. This is what you suggested. Examples: NSPropertyListSerialization, NSJSONSerialization.
Create class methods on some appropriate existing class. Example: UIKit uses a category to add class methods to NSValue, such as valueWithCGRect: and valueWithCGPoint:.
Create a singleton that understands some group of related messages. Examples: [UIApplication sharedApplication], [NSFileManager defaultManager].
Create plain old C functions. Examples: UIImagePNGRepresentation, UIRectFill, NSLog, NSStringFromCGPoint, and a pantload more.
If the code operates on some object in particular, add a method the the object's class using a category. Example: UIKit adds sizeWithFont:, drawAtPoint:withFont:, and related methods to NSString using a category.

I use that exact approach to provide my global CocoaUtil class that provides various application services.
However you can simply define global C functions that do Objective-C things; for example:
Util.h:
extern NSString *helloWorld(int i);
Util.m:
NSString *helloWorld(int i)
{
return [NSString stringWithFormat:#"Hello World %d", i];
}
However, I use the Objective-C class approach as it provides better "namespace" support, ala C++.

Related

Is it possible to extend(heritance) class in Objective-c as is traditionally conceptualised in other languages?

I am having a lot of repeated code throughout my app classes given that some properties & method are stable across all my views.
I am looking to extend whatever class I am working with so that it automatically inherit all properties and methods that I think should be common to those classes.
I looked into the apple guide on extending classes. But I am left confused in the terms of the level of heritance that I can achieve.
I've successfully created Categories on lets say a UIViewController. But that limits me to only be able to declare Methods. I can not declare Properties on my Category and call them in side my Category or in the Extended Class. I want to be able to declare Properties and use it inside and outside my Extended-Class.
Its my first time trying to extend a class in objective-c taking full advantage of heritance but I do not know if it is possible. Am I missing something?
As an example in the code below every time I try to instantiate activityIndicatorView inside my method _activityIndicator it wouldn't recognise it. I've tried #syntetize and #dynamic but it doesn't work
NOTE: I am seeking an answer based on how to achieve heritance of methods and propeties. not highlighting what categories cant do (as I already tried and know I cant have properties there)
My attempt went as far of
#import <UIKit/UIKit.h>
#interface UIViewController (customViewController1)
#property (strong, nonatomic) UIView *activityIndicatorView;
- (void) _activityIndicator;
#end
#import "UIViewController+customViewController1.h"
#implementation UIViewController (customViewController1)
- (void) _activityIndicator {
//......
}
Your question is too broad, plus it is not clear what your problem is. Yes, you can subclass in Objective-C.
This is all very well documented in Apple's document "Object-Oriented Programming with Objective-C", section "The Object Model", subsection "Inheritance".
Categories are a nice way to add functionality while at the same time conforming to an object oriented principle to prefer composition over inheritance.
Categories only add methods, you can't add variables to a class using categories. If the class needs more properties, then it has to be subclassed.
When you use the term “extend”, you're talking about creating a subclass. This is, IIRC, how the term is used in Java and some other languages.
Apple uses the term differently (as Hermann Klecker hinted in his first comment). They literally mean extending an existing class with more functionality (in the form of methods)—that's what categories do. This is the normal English definition; extending something in the real world generally does not create a new thing.
Objective-C supports subclasses, too; it just doesn't call them “extending” the superclass. It's called creating a subclass, which inherits from the superclass.
Strctly spoken you cannot add a property to an existing class any differnt than creating a subclass.
If you cannot halp yourself and subclassing is not an option, then you can extend the class with getters and setters for the property that you want to store within the class.
Instead of really storing it as a member/instance variable/property, which you can't do, you could store the object (it cannto be a scalar, must be an object) in the global space using objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy).
This is some sort of global dictionary with two keys, the key itself and the ojbect to which you want to associat the stored object to. In your case that is the object of the type of the exended class. The setter stores it there and the getter receives it from there using objc_getAssociatedObject.
You delete an association by sending nil as value to objc_setAssociatedObject
AFAIK retained associated objects (values) are released shortly after the object that holds the associateion (object) is deallocated.
For further details see the Ojbective-C Runtime Reference https://developer.apple.com/library/ios/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html
Just: I do not say that this is strictly following the OO paradigm. :-)

Adapting a few Java-based singleton objects to Objective-C [duplicate]

This question already has answers here:
Global Variables for Class Methods
(2 answers)
Closed 8 years ago.
I've decide to rewrite a java-based game prototype I've been working on in Objective-C. The iOS platform will be a better fit.
Unfortunately I'm having to learn Obj-C at the same time. In the Java game, there were a few libraries that were instantiated by the main game class, and accessed statically when needed. This meant that I could the overhead of new instances each time.
i.e.:
Game.getRNG().nextInt() or Game.getNoiseGen().noise( x, y )
I'm trying to understand the best method to replicate this in Obj-C. I've looked at examples of singletons and am trying this method, but I'm not sure if this is the best way to do this.
The above code, would apparently translate into something like:
[[[Game getInstance] getNoiseGen] noise]
Is there a better way to create a single instance of library classes and statically reference them from anywhere inside my application code?
For creating a singleton make sure you only create the static instance once, you can do this by using GCD.
+ (id)sharedInstance;
{
static dispatch_once_t once;
static id sharedInstance;
dispatch_once(&once, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
and you can then:
Game *game = [Game sharedInstance];
//...
CGPoint point = CGPointMake(x, y);
[[game noiseGen] noise:point]
//...
Singletons are considered an anti-pattern and should be avoided if possible.
Just from looking at your example you also violate the Law of Demeter, might be worth a read to see if you can improve there.
If I understand your Java model correctly there is no reason why you cannot translate it directly into Objective-C, which certainly has the advantage that you are familiar with it - helpful while you're learning a new language.
By "there were a few libraries that were instantiated by the main game class, and accessed statically when needed" I take it that either:
The main class declared global variables of the appropriate types and initialised them; or
The classes themselves have a global variable which holds a reference to an instance of themselves.
You are not generating "singletons" here, just objects you want to share. Also given that your main class created them they always exist. Combined this means you've no need to use any of the "singleton" schemes which delay creation until first use and deal with one-time thread-safe initialisation.
All you need is the model for global variables in Objective-C. In outline this is:
Declare the variable as extern in a header file
Define the variable in an implementation file
In outline, your MainGame.h:
#import "SharedGameObject.h"
#interface MainGame : NSObject
extern SharedGameObject *TheSharedGameObject;
...
#end
and MainGame.m
#import "MainGame.h"
SharedGameObject *TheSharedGameObject;
- (id) init
{
TheSharedGameObject = [SharedGameObject new];
...
}
Now every other class which import MainGame.h has access to the same shared object using TheSharedGameObject. This is the model Apple used for NSApplication and it associated NSApp global variable.
HTH

Subclass NSArray in Objective-C

I need to have a class, which has all methods of NSArray, which behave the same way, but 2 methods are modified.
I want to override these 2 methods in my custom class:
1) countByEnumeratingWithState:objects:count:
2) objectAtIndex:
After hours of research I don't see any reasonable way to do that, because:
I don't want to use category, because not all NSArray instances should have the modified behaviour. (Plus that throws warnings)
I don't want to re-write all initializers plus all arrayWith... methods + the primitive methods + implemented my own storage (because this functionality is already implemented in Cocoa, right? Why would I re-implement all the functionality of a class that is already there?)
If I have my custom class inherit NSObject and use NSArray as storage in an ivar, then all NSArray's methods are not available when programming in Xcode (even if I can forward them to the NSArray ivar)
I had some success overwriting the method implementations on demand by using method_setImplementation(...), but still can't figure out a way to have dynamically a class created at runtime, which then will have custom implementation of the 2 methods I mentioned.
Looking forward to your ideas! Thanks
Mantra: If something is hard (or seems like it requires more code than is necessary), it is likely that your design is counter to the design principals of the iOS / OS X frameworks. It may yield a better solution to revisit your design.
To answer the original question, if you want to subclass NSArray (or NSMutableArray), you need to implement the primitive methods, no more, no less.
The primitive methods are the methods declared in the #interface of the class itself. I.e.:
#interface NSArray : NSObject
- (NSUInteger)count;
- (id)objectAtIndex:(NSUInteger)index;
#end
And for NSMutableArray:
#interface NSMutableArray : NSArray
- (void)addObject:(id)anObject;
- (void)insertObject:(id)anObject atIndex:(NSUInteger)index;
- (void)removeLastObject;
- (void)removeObjectAtIndex:(NSUInteger)index;
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;
#end
If you subclass NSMutableArray and implement the above 7 methods (the two from NSArray, too), you will have an NSMutableArray subclass that is compatible -- assuming your methods are correctly implemented -- with all APIs that consume mutable arrays.
This is because of the way class clusters are designed. The public classes are abstract; are never directly instantiated. They provide a primitive interface that contains the class's core functionality and then concrete implementations of all the other non-primtive API (save for the initializers, see below) that are implemented in terms of the primitives. Concrete, private, subclasses then override all the primitives and some of the non-primitives to provide optimal behaviors for specific configurations.
I want to have an NSArray instance for a library I'm working on and I
want to have it working transparently for the users of my library. Ie.
for them should be no difference between using a normal NSArray and
the modified class I'll be providing. Ie. it's a storage concern,
which the end users should not be concerned with and the interface
should remain the same as NSArray - therefore loosing all init methods
is not really an option at that point.
The initialization methods are not a part of the primitive interface to NSArray. You are adding a requirement above and beyond "make a class compatible with NSArray / NSMutableArray" as defined by the documentation. Nothing wrong with that, just pointing it out.
The reason why this is the case is because it is exceptionally rare to subclass the collection classes to provide the kind of business logic you describe. Collections are very generic in their behavior whereas such business logic that conditionalizes collection behavior would be done in a class that manages the overall model layer object graph.
If you really want to do this, provide an implementation of whatever init* methods you want, calling through to your wrapped generic instance as needed. There isn't anything so special about the implementations of the initializers that you are going to lose much in doing so.
No need to implement all of them, either. Implement one or two and #throw a descriptive exception on the rest.
If you do decide to forward the ones that accept var-args, you can't directly because there are no va_list accepting methods. Instead, you'll want to convert the va_list of arguments into a language array (i.e. id[] foo = malloc(... * sizeof(id));) and pass it to initWithObjects:count:.
Some other comments:
What you are doing [provide full NS*Array interface in a subclass] seems hard because it is not a common pattern and the framework designers saw no need to create a design to support it. Custom behaviors at the primitive collection levels are almost always better implemented at a higher level within the object graph. Almost always.
method_setImplementation() and dynamic class creation is academically interesting, but pretty much never a solution. Obviously, mucking with the NSArray or NSMutableArray classes (or the concrete implementation classes) is going to blow up the rest of the frameworks that rely upon standard behavior. Beyond that it, it is a pattern of dynamic OO composition that is not really intended to be used in Objective-C; it'll be a pain in the ass to maintain.
Instead of subclassing NSArray why not create a new class based on NSObject that contains an NSArray?
Then you can use all the functions of the NSArray and add your own methods that will do custom actions with it?
Or do you NEED an NSArray?

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

Objective-C Basic Class question

So I'm a bit rusty getting back into programming and I can't seem to find a good reference for understanding the structure for what I am trying to achieve. So, without further ado I am looking at creating and Class object such as.
#import Assets.h
#interface MainRecord: NSObject {
Assets* assets;
...
}
...
#end
Having a class object within a class, do i need to initialize when the object is created in main? I want to make sure each instance created for MainRecord will always be associated with it's Assets.(in the future these will be written to a file) All of which is mainly for readability and ease of adding objects to this class.
I recommend reading (at least parts of) The Objective-C 2.0 Programming Language, a guide published by Apple. The section called "Defining a Class" will answer the bulk of your questions.
Basically, you don't initialize instance variables in main() — the class defines methods that handle its own variables. (This is common practice for object-oriented programming languages.) In Objective-C you initialize instance variables in an -(id)init method and release them in -(void)dealloc method to avoid leaking memory. For example, see all the -initWith... methods in NSString.