Automatically call class method in objective c - objective-c

my situation:
a dashboard controller who register the widgets inside it and automatically builds the view.
widget classes that are going to populate the dashboard, who adopt <widget> protocol(some informal methods required), and need to be registered in the dashboard class so the dashboard singleton knows who wants to be in.
the dashboard class has +(void)register:(Class<widget>)w; that simply register the classes who wants to be in in an NSArray
I need each widget class to call automatically that method.in c++ i used to make a boolean static variable that i would initialize with that method.
Language = objective-c

The objective-c runtime will call two methods when a class is first loaded. +load and +initialize. I believe what you want could be done by calling [self register] from within +initialize.

A way you could do it is with the runtime:
Grab a list of all the classes known to the runtime.
Iterate the list, and check to see if the class conforms to your widget protocol
If it does conform to the protocol, invoke the +register: method or whatever
Regarding step #2, you can't use the +conformsToProtocol: method, because one of the classes you'll iterate is the NSZombie class, which triggers an exception whenever you invoke a method on it. Thus, you'd want to use the class_conformsToProtocol() runtime function instead.

Related

Is it possible to initialize a property in a category before any category method is called?

Is it possible to initialize a property in a category?
For example, if I have a mutable array property called nameList in a class. Is it possible to have a category created for this class to add an object to the array property before any of the category method is called?
If I understand you correctly, and others are interpreting your question differently, what you have is:
A class with a property
A category on that class
And you want to call a particular method automatically before any category method is called on a given instance, that method would "initialise" the category methods by modifying the property.
In other words you want the equivalent of a subclass with its init method, but using a category.
If my understanding is correct then the answer is no, there is no such thing as a category initializer. So redesign your model not to require it, which may be to just use a subclass - as that provides the behaviour you are after.
The long answer is you could have all the category methods perform a check, say by examining the property you intend to change to see if you have. If examining the property won't determine if an object has been "category initialized" then you might use an associated object (look in Apple's runtime documentation), or some other method, to record that fact.
HTH
Addendum: An even longer/more complex solution...
GCC & Clang both support a function (not method) attribute constructor which marks a function to be called at load time, the function takes no parameters and returns nothing. So for example, assume you have a class Something and a category More, then in the category implementation file, typically called Something+More.m, you can write:
__attribute__((constructor)) static void initializeSomethingMore(void)
{
// do stuff
}
(The static stops the symbol initializeSomethingMore being globally visible, you neither want to pollute the global name space or have accidental calls to this function - so you hide it.)
This function will be called automatically, much like a the standard class + (void) initialize method. What you can then do using the Objective-C runtime functions is replace the designated initializer instance methods of the class Something with your own implementations. These should first call the original implementation and then an initialize your category before returning the object. In outline you define a method like:
- (id) categoryVersionOfInit
{
self = [self categoryVersionOfInit]; // NOT a mistake, see text!
if (self)
{
// init category
}
return self;
}
and then in initializeSomethingMore switch the implementations of init and categoryVersionOfInit - so any call of init on an instance of Something actually calls categoryVersionOfInit. Now you see the reason for the apparently self-recursive call in categoryVersionOfInit - by the time it is called the implementations have been switched so the call invokes the original implementation of init... (If you're crosseyed at this point just draw a picture!)
Using this technique you can "inject" category initialization code into a class. Note that the exact point at which your initializeSomethingMore function is called is not defined, so for example you cannot assume it will be called before or after any methods your target class uses for initialization (+ initialize, + load or its own constructor functions).
Sure, it possible through objc/runtime and objc_getAssociatedObject/objc_setAssociatedObject
check this answer
No it's not possible in objective c.Category is the way to add only method to an existing class you can not add properties in to this.
Read this
Why can't I #synthesize accessors in a category?

Objective C delegates and class methods vs instance methods

There is a similar question to mine on the following link
but it doesn't quite answer my query.
I am setting a helper class for Facebook (follows the delegation pattern) . An example of one of the class methods would be:
+ (void)openSession:(id)delegate;
This method calls a the Facebook openActiveSessionWithReadPermissions method which expects a completionHandler block. Would it make sense to call the delegate method, say sessionStateChanged in the block as follows?
[delegate sessionStateChanged];
Or is it better to use instance methods for the Facebook helper class and call the delegate using [self.delegate sessionStateChanged] in the completionHandler block.
You would be better off with a block parameter rather than a delegate as a parameter if it is just for a single callback.
+ (void)openSession:(void (^)(void))sessionStateChangedBlock
That way you don't have to worry about defining a delegate protocol.
If you want to use a delegate, you will have to define a delegate variable at the class level. You can't use [self.delegate sessionStateChanged] because you are saving the delegate as a class variable. self is only available in an instance of the class.
I tried both methods i.e. using class and instance methods. Any of them will do, though to follow the proper delegation pattern I believe using instance methods is more appropriate.

In Objective-C, the rule that designated initializer always get called is not always obeyed?

Can we rely on the fact that in Objective-C, the rule is that a class's designated initializer is always called for sure? Or can we say, it should be almost always true, except a couple of exceptions? For example, for UIView, the docs says:
initWithFrame:
If you create a view object programmatically, this method is the
designated initializer for the UIView class. Subclasses can override
this method to perform any custom initialization but must call super
at the beginning of their implementation.
If you use Interface Builder
to design your interface, this method is not called when your view
objects are subsequently loaded from the nib file. Objects in a nib
file are reconstituted and then initialized using their initWithCoder:
method
Or can we say that, if it is programmatically, the rule should always apply for well designed classes, but Interface Builder is a bit different because it sort of "revive" or build the object from a non-programmatic way. If so, are they other exceptions in general when we do iOS programming?
The fact is that class designed with Interface Builder are unarchived and not initialized .
Being archived involves that the class is not initialized but unarchived, so the initWithCoder: method takes responsibility for setting up the control when it's loaded using the archived attributes configured by Interface Builder.
You should put your initialization operations in the awakeFromNib: method that gets called in each case after the object is loaded, thus you will be sure that your initialization statements will be called .

Right way to create a customizable uiview

this question is about "style", because i think this is a very common problem and i'm looking for an elegant solution.
I have created some "advanced" UIView and i try to make them very customizable.
Usually i create the UIView structure inside a custom init method, but i need to know the value of all customizable parameter inside init method so sometimes i need a very long init method like:
initWithFrame:color:font:verticalspace:verylonglist:
I tried to use delegate design pattern but i need also to pass delegate inside init method.
My actual best solution is to leave empty the init method and move everything about layout inside a "configure" method. everytime i chance a property like background color or font i will call this method and i will rebuild the view.
I think there is a best way to solve this problem...
I'd be curious to see the code of UITableView Class, because with that class you can pass a delegate outside init method.
Check out something like a UIButton or UILabel. They both have tons of configurable aspects, however to simply create an instance of one of those objects, they need very little information.
In general, provide init methods that allow the consumer of your class to specify the least amount of information for the class to work.
If you do want to give the consumer a way to initialize the class with a bunch of values, consider using some sort of initWithDictionary: method that takes an NSDictionary of parameters. This keeps your method names short and allows the user to customize an arbitrary number of settings for your class.
You could also consider providing a way for the consumer to request an instance with some standard set of values. UITableViewCell, for example, has an initWithStyle:reuseIdentifier: method. The important part is the style - UITableViewCell provides several default styles like UITableViewCellStyleDefault and UITableViewCellStyleSubtitle.
I don't know if it is the standard/best practices way but I use a dictionary in cases like this and pass that to an initWithDictionaryinitializer. Would be possible too to create a class method that returns a 'default settings' type dictionary which can then be customized (and delegate set), so that not every param needs to be specified whenever the class is used.

what is the different between class method and delegate method in iPhone

I have a questions about the iPhone application. I am the green of the iPhone application. When I read the document(PDF) download from the apple developer website (online version). I found that the document always mentions different methods of the library.
There are
1) Class method
2) Instance method
3) Delegate method
I understand the use and meaning of the instance method, which is called by a instance.
let's say the delegate methods is the connection:didReceiveAuthenticationChallenge and the class method sendSynchronousRequest:retruningResponse:error:.
However, I don't understand about the different between the class method and the delegate method. Is the class method for the whole class? or whole project? What it means of the delegate? and where should I put the code after I modify the content of the delegate? How can I call the method?
Can anyone help me. Thank you very much.
It is another question about the delegate method. And I don't how to solve the problems. Please help me. Thank you.
HTTP status code = 0 (iPhone) (objective c)
Suppose you have a class Foo and an instance of that, Foo* foo.
Then, the class method is a method which is sent to the class:
[Foo classMethod];
while the instance method is a method sent to the instance:
[foo instanceMethod];
The delegate method is a method which the instance of the class calls. So, you typically implement another class Delegate with an instance Delegate* delegate, and do
[foo setDelegate:delegate];
Then, the object foo calls the delegate method of delegate at appropriate times:
[delegate delegateMethod];
This is a way to receive an event from the system API.
Apple provides extensive documentation on the fundamentals for Objective-C and Cocoa - if in doubt, this should be your first stop.
The Objective-C Programming Language - Class Objects:
[...] a class definition can include methods intended specifically for the class object—class methods as opposed to instance methods. A class object inherits class methods from the classes above it in the hierarchy, just as instances inherit instance methods.
Cocoa Fundamentals Guide - Delegates and Data Sources:
A delegate is an object that acts on behalf of, or in coordination with, another object when that object encounters an event in a program.
The delegating object is often a responder object—that is, an object inheriting from NSResponder in Application Kit or UIResponder in UIKit — that is responding to a user event. The delegate is an object that is delegated control of the user interface for that event, or is at least asked to interpret the event in an application-specific manner.
And some related background in The Objective-C Programming Language - Protocols:
Class and category interfaces declare methods that are associated with a particular class — mainly methods that the class implements. Informal and formal protocols, on the other hand, declare methods that are independent of any specific class, but which any class, and perhaps many classes, might implement.
A delegate method is a method that is defined in a classes delegate protocol. They are added to your class but your class must have the objects delegate protocol. They are usually used by the object but is something that you must define for the object. NSTableView and UITableView use delegate methods to populate their data. A class method is just one that you define in your interface.