class_addmethod and Public API - objective-c

I am developing a Game Project and wish to use the Object Composition pattern to give me a great deal of flexibility. I currently override message forwarding methods in order that the Composite can invoke the methods of its Components.
The only downside to this is that -forwardingTargetForSelector: only works when there is to be only one target. If I have a Composite with two Components that have the same selector, then I will have to resort to using the (much slower) -forwardInvocation method and perform the NSInvocation on both the targets.
From reading a few books on advanced Objective-C and Runtime reference, it seems that I may be able to forward messages by dynamically creating an implementation that will invoke the IMP in the child Component Classes. I would use the Runtime method class_addmethod to do this.
My question is, does anyone know if Apple considers this to be private API and thus against App Store Rules? Has anyone used class_addmethod in Apps that have passed review?
It is common knowledge that method swizzling is not allowed in the store, but this is not exactly the same thing. One typical example was swizzling the -drawRect: on UINavigationBar, before the Appearance API was available. This would be adding methods to my own object rather than messing with Apple's own API.
Thanks for Reading!
Lawrence

From what I've read as long as you're not swizzling Apple provided classes to alter functionality, you should be fine. The Objective-C runtime isn't a private API, so if this is all happening on your own code then you should be fine to do this.

Related

Obj-C, how should I pass several app delegate properties into an cocoa touch framework method?

How should I pass several app delegate properties into a cocoa touch framework method?
I'm thinking of using a protocol with required properties and use the type of protocol as my method argument type.
Obviously the framework needs to know what properties exist.
However, it doesn't feel right to pass the app delegate into a method like this.
PS. I know a good question shouldn't include "should" but I think it's relevant in this case.
Yes, don't pass the AppDelegate into your own custom code. That creates a coupling that is far far too tight.
Much better to at the right point unpack the properties you need, pack those into a struct and pass that into your framework.

xCode / Objective-C Anatomy Analogies - Help a Noob Get It

OK so I'm trying to get started with Xcode and I have some experience with OOP in general but mostly I'm used to scripting. Anyhoo, I'm trying to get a handle on some concepts in objective C and xcode and I'm having some problems putting everything together.
For starters, I'm having trouble understanding what delegates and protocols do. I think it would be useful if someone could explain this with a simple analogy of a postman, or a teacher, or a factory or something. I don't understand the difference between a method in a delegate and a regular class methods.
Say I have a Class Postman. Now postman has methods sortMail() and deleteMail(). What's an example of a delegate method. And if a delegate is used, where is the data returned? Inside the delegate? Do I have to instantiate the delegate and then read results from it or does the delegate kinda give the results back to the calling object? Where do protocols come in...
Simple examples please :) Baby steps.
Protocols and Delegates go together frequently. It helps to understand what a protocol is first.
Protocol
A protocol is a way of having a class promise to implement a standard set of methods.
Example: A certified electrician has a certain set of skills that all certified electricians will have. If you need someone to do something that a certified electrician is certified to do, then any certified electrician should be able to do it (in theory at least).
Delegate
Now a delegate is an object that has been given a responsibility to fulfill certain requirements. One object can be given the responsibility of fulfilling a need of another object.
Example: When building a house, the house needs to have wires run etc. This responsibility has been given to a certified electrician, and we know he can do it because he's certified (i.e. implements a certain protocol).
Putting it all together in a Cocoa context:
A UITableView needs cells supplied so it can display them. To supply the cells, a class will need to be created (or at least specified) which implements the UITableViewDataSource protocol. That guarantees that the class does the needed things to supply the UITableView with the needed cells.
So the UITableView delegates the responsibility of providing the cells to a certain class object which implements the protocol which guarantees that the object knows how to supply the needed cells.
Example
A delegate is an object that handles particular functionality for another object - as in "Object A delegates certain functionality to object B".
For instance, you may use an instance of Apple's class NSURLConnection to make a request for a web service, but Apple's code obviously won't know what to do with the data it downloads, so you provide a delegate object to handle that functionality. NSURLConnection then delegates that functionality to your object by passing it messages when it needs to do something like handle the data it downloads.
Another example is a table view. Apple have written a lot of code to display table views and handle interactions with them, but it doesn't know what data you want to display or what needs to be done with that data when somebody interacts with it. So you can provide delegate objects for these things. When a table view needs to know what data to display, it asks your delegate to fetch the data for it. When the user selects an item, it asks your delegate to handle it.
A protocol is simply a way of describing what messages the delegate is supposed to understand. There can be informal protocols, where it's just described in the documentation, and formal protocols, which are defined in a header file.

Obj-C component-based game architecture and message forwarding

I've been trying to implement a simple component-based game object architecture using Objective-C, much along the lines of the article 'Evolve Your Hierarchy' by Mick West. To this end, I've successfully used a some ideas as outlined in the article 'Objective-C Message Forwarding' by Mike Ash, that is to say using the -(id)forwardingTargetForSelector: method.
The basic setup is I have a container GameObject class, that contains three instances of component classes as instance variables: GCPositioning, GCRigidBody, and GCRendering. The -(id)forwardingTargetForSelector: method returns whichever component will respond to the relevant selector, determined using the -(BOOL)respondsToSelector: method.
All this, in a way, works like a charm: I can call a method on the GameObject instance of which the implementation is found in one of the components, and it works. Of course, the problem is that the compiler gives 'may not respond to ...' warnings for each call. Now, my question is, how do I avoid this? And specifically regarding the fact that the point is that each instance of GameObject will have a different set of components? Maybe a way to register methods with the container objects, on a object per object basis? Such as, can I create some kind of -(void)registerMethodWithGameObject: method, and how would I do that?
Now, it may or may not be obvious that I'm fairly new to Cocoa and Objective-C, and just horsing around, basically, and this whole thing may be very alien here. Of course, though I would very much like to know of a solution to my specific issue, anyone who would care to explain a more elegant way of doing this would additionally be very welcome.
Much appreciated, -Bastiaan
I don't think that sending the container object all of its components' messages is what Mick West was suggesting--that doesn't help to remove the idea of a "monolithic game entity object".
The eventual goal is to have the components communicate directly with one another, with no container object at all. Until then, the container object acts as glue between old code that expects a single object for each game entity and the new component-to-component system.
That is, you shouldn't need to use message forwarding at all in the final product, so ignoring the warnings, or declaring variables as id for now to quiet them, isn't all that ugly. (The plan as laid out by the article is to eventually remove the very code that is causing your warnings!)
A simple way to have those warnings disappear would be to declare the instance variables of type id
That way the compiler assumes you know what you're doing regarding the type of the object and that the object will respond to whatever messages you send to it, or if it doesn't you don't care.
Override your GameObject's -respondsToSelector: method. Your implementation should in turn send a respondsToSelector: message to each of its instances, and return YES if any one of them returns YES.
You can use type of id - or you could invoke the methods using performSelector methods, or create an NSInvocation if the arguments are complex. This is all just a way of getting around compiler warnings, however. If your objects respond to several methods, then possibly declaring a protocol might help, although the same caveat applies.
Another option if I understand the problem correctly is to implement a protocol. This is link an interface in java and variables can be declared like this:
id anObjectRef
That way the compiler understands that the object referred to by anObjectRef conforms to the protocol.
There are also methods that can tell you if an particular object conforms to a specific protocol before you cast or assign it.

how do i know when to use a datasource or delegate protocol when using a UI object in my project?

for example the UIPickerView, in the tutorial that i am learning i had to include the datasource and delegate protocols in my project for the pickerview to work. how would i know on other objects?
In general that is explained in the documentation of the individual object. For example http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIPickerView_Class/Reference/UIPickerView.html
In the Overview section it explains that, "the delegate must adopt the UIPickerViewDelegate protocol" and that, "the data source must adopt the UIPickerViewDataSource protocol"
From http://developer.apple.com/iphone/index.action just type the name of the object you are interested in into the search box and the documentation should explain everything needed to make it go.
To note, the UIPickerViewDelegate/Datasource are representative of the Delegate design pattern (see Cocoa Design Patterns) and are repeated throughout the Cocoa UI hierarchy as a method of modifying behavior of an object without having to subclass. It's quite graceful, less entropic, fosters the single responsibility principle, and reduces coupling. The delegation pattern is seen throughout all of Cocoa, not just the UI classes, so you can expect to see it often.
To know about other objects, you pretty much have to visit the Framework Library Reference for the specific class at the Apple Developer Center or from within the help system of Xcode. You can almost presume that all data backed UI objects will have datasource (delegate) methods, and most UI objects will have delegate methods.

Which object called another object's method in Obj-C

I am looking to write a plugin controller in Cocoa that loads bundles, and exposes a specific set of methods for the plugins to call.
My question is this: is it possible to know (any) info about the object that called a method in the controller. When an instantiated plugin calls a method in my plugin controller, I would like to know which of the plugin instances called the method, without having to rely on the plugin sending a pointer to itself as a parameter (I could always validate the pointer they send, but I want to keep the API methods as simple as possible).
There may be no perfect solution (and there are simple workarounds), but it's always good to learn some new tricks if possible (or the reasons why it's impossible).
Thanks in advance.
It's not possible without walking the stack, and possibly not even then. There's not even a guarantee that a given message was sent from within a method — and even if it was, it may not be the method that you think of as being the "caller." For example, assuming your plugins have access to Cocoa, your controller methods could be called by an NSTimer.
In general, this is not practical. The normal way to accomplish this is to have objects pass themselves around. If you're trying to do this for security reasons, you'll want a much more robust solution anyway, because Cocoa's object model was not designed with that in mind. It's way too easy for objects to lie about who and what they are.
Well, you could throw an exception, catch it and examine its stacktrace.
Assuming that Objective-C supports exceptions, of course.
Sending a reference to the calling object is how this is usually done. As an alternative, you could have your host code provide a proxy object for plugins to talk to. As each plugin is loaded, create a new proxy object for each to talk to.