I asked a question earlier on here regarding the use of First Responder - and got a response here:
Trouble with First Responder
Would anyone mind giving me a 'dummies' version of this? Being new to Cocoa, I don't really know where to start with either one of these methods. I award answers quickly
Zach
First Responder is specifically this.
What you're asking about, though, is target-action. You have a UI object (button, menu item) that you need to cause multiple things to happen, but the UI object only sends one action.
Hence the solution: Make that action do multiple things.
Hook the UI object up to an action method you implement in your controller object (in your case, the document). In that method, do all the things the button needs to cause.
The subclassing solution is basically the same thing, except instead of hooking the UI object up to your document, you hook it up to the font manager, but you also make the font manager an instance of a subclass of NSFontManager that you create, rather than an instance of NSFontManager directly. In your subclass, you override addFontTrait: and add the other behavior in your implementation. At either the start or the end of that method, you send [super addFontTrait:sender] to invoke NSFontManager's implementation, so the original implementation gets done.
Long paragraph, but it's not actually all that much more work: The difference is just making the subclass and making the instance an instance of that subclass.
You've said before that “the Apple Documentation is incredibly vague”, but it's really not. There just happens to be a lot of it, and maybe you haven't been looking at the right documents.
These are the documents you need to read, from start to finish, and in order:
EDIT: This list is for Xcode 3. I posted an updated (for Xcode 4) version of this list in another answer.
The Objective-C Programming Language
The Memory Management Programming Guide for Cocoa
The Cocoa Fundamentals Guide (which explains target-action, among other things)
Application Architecture Overview
Resource Programming Guide
Interface Builder User Guide
The Xcode 3 guides:
Xcode Project Management Guide
Xcode Workspace Guide
Xcode Build System Guide
Xcode Debugging Guide
Document-Based Applications Overview
There is also an Instruments User Guide, but, unfortunately, that one is vague—or, to be more precise, incomplete. It omits a lot of useful information, like how to use Instruments' Zombies template to debug crashes. It's a high-level overview, nothing more.
Also, bookmark these:
Cocoa Core Competencies, a quick reference to all the concepts you need to use
The Foundation Framework Reference
The AppKit Framework Reference
The Core Foundation Framework Reference
The Core Graphics Framework Reference
That's a lot of reading, but it'll tell you everything you need to know, and that order is roughly the order you'll need to know it in.
The other answer says that you have two options:
First: Do replace the action by the one created by you and then implement the feature of the original version yourself. In this case, it suffices to just call the appropriate method of NSFontManager. That is, you add the original functionality to your own implementation of the method. This way, both actions are executed.
Second: Subclass the class where the original functionality is implemented and add your implementation by overriding the method that is called -addFontTrait. This way, your code gets executed "alongside". This question might help you to find the correct implementation.
So, the essence is that you can either add the original functionality to your implementation or the other way around. In this case, I would try the first one.
Related
I have used pragmas in Pharo Smalltalk and have an idea about how they work and have seen examples for what they are used in Pharo.
My questions are:
what are pragmas conceptually,
to what construct do they compare in other languages,
when should i introduce a pragma?
I already found an interesting article about their history: The history of VW Pragmas.
You must think of it as Annotations attached to a CompiledMethod, or if you want as additionnal properties.
Then, thanks to reflection, some tools can walk other compiled methods, collect those with certain annotations (properties) and apply some special handling, like constructing a menu, a list of preferences, or other UI, invoking every class methods marked as #initializer, or some mechanism could be walking the stack back until a method is marked as an #exceptionHandler ...
There are many possibilities, up to you to invent your own meta-property...
EDIT
For the second point, I don't know, it must be a language that can enumerate the methods, and can attach properties to them.
The third point is also hard to answer. In practice, I would say you would use some already existing annotations, but very rarely create a new one, unless you're trying to create a new framework for exception handling, or a new framework for GUI (you want to register some known events or some handlers...). The main usage I would see is for extending, composing an application with unrelated parts, like a main menu. It seems like a relatively un-intrusive way to introduce DECLARATIVE hooks - compared to the very intrusive way to override a well known method TheWorld>>mainMenu. It's also a bit lighter than registering/un-registering IMPERATIVELY via traditional message send at class initialization/unoading. On the other hand, the magic is a bit more hidden.
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.
My first post here (anywhere for that matter!), re. Cocoa/Obj-C (I'm NOT up to speed on either, please be patient!). I hope I haven't missed the answer already, I did try to find it.
I'm an old-school procedural dog (haven't done any programming since the mid 80's, so I probably just can't even learn new tricks), but OOP has my head spinning! My question is:
is there any means at all to
"discover/find/identify" an instance
of an object of a known class, given
that some OTHER unknown process
instantiated it?
eg. somthing that would accomplish this scenario:
(id) anObj = [someTarget getMostRecentInstanceOf:[aKnownClass class]];
for that matter, "getAnyInstance" or "getAllInstances" might do the trick too.
Background: I'm trying to write a plugin for a commercial application, so much of the heavy lifting is being done by the app, behind the scenes.
I have the SDK & header files, I know what class the object is, and what method I need to call (it has only instance methods), I just can't identify the object for targetting.
I've spent untold hours and days going over Apples documentation, tutorials and lots of example/sample code on the web (including here at Stack Overflow), and come up empty. Seems that everything requires a known target object to work, and I just don't have one.
Since I may not be expressing my problem as clearly as needed, I've put up a web page, with diagram & working sample pages to illustrate:
http://www.nulltime.com/svtest/index.html
Any help or guidance will be appreciated! Thanks.
I have the SDK & header files, I know what class the object is, and what method I need to call (it has only instance methods), I just can't identify the object for targetting.
If this is a publicly declared class with publicly declared instance methods (i.e., you have the header for the class and it has instance methods in it), there is probably a way in this application's API to get an instance of the class. Either you are meant to create one yourself, or the application has one (or more) and provides a way to get it (or them). Look at both the header for the class in question and the other headers.
I initially said “there must be a way…”, but I changed it, because there is an alternative reason why the header would have instance methods: The application developer does not intend those instance methods for plug-in use (and didn't mark them appropriately), or did not mean to include that header in the application/SDK (they included it by accident). You may want to ask the application developer for guidance.
If it is not a publicly declared class or its instance methods are not publicly declared, then the application does not support you working with instances of the class. Doing so is a breach of the API contract—not a legal contract, but the expectations that the application has of its plug-ins. If you breach the API contract, you will cause unexpected behavior, either now (not necessarily on your own machine/in your own tests) or in the future.
If the class's public declaration contains only class methods, then perhaps what you're after is not an instance at all—you're supposed to send those messages to the class itself.
This is not possible without having you register each instance in a dictionary as it is created. I.e., override some common factory method at a higher level which does this bookkeeping work. This will fall down when you use delegates that you may not control though, keep that in mind.
I do question the need to even do this at all, but I don't know your problem as well as I perhaps would need to, to recommend a different, more apt way of accomplishing the actual task at hand.
Just as a corollary to the above; I did look at the runtime to see if there was anything that I actually forgot about, but there is not. So my above statement with regards to you requiring to do that bookkeeping yourself, still holds I'm afraid.
Edit:
Based on your diagram (my apologies, just noticed the link after I posted this answer); I would suggest that if you control the classes that are being returned to you, just add a property to them. I.e., add a "name" property that you can set and keep unique. Then just pass the message to each instance, checking whether or not that object is the one you want. It's not particularly clever or anything like that, but it should work for your purposes.
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.
When do you recommend integrating a custom view into Interface Builder with a plug-in? When skimming through Apple's Interface Builder Plug-In Programming Guide I found:
Are your custom objects going to be used by only one application?
Do your custom objects rely on state information found only in your application?
Would it be problematic to encapsulate your custom views in a standalone library or framework?
If you answered yes to any of the preceding questions, your objects may not be good candidates for a plug-in.
That answers some of my questions, but I would still like your thoughts on when it's a good idea. What are the benefits and how big of a time investment is it?
It's perfectly reasonable to push the view and controller classes that your application uses out into a separate framework — embedded in your application wrapper — for which you also produce an Interface Builder plug-in.
Among other reasons, classes that are commonly used in your application can then be configured at their point of use in Interface Builder, rather than in scattered -awakeFromNib implementations. It's also the only way you can have your objects expose bindings that can be set up in Interface Builder.
It's a bit of coding, but for view and controller classes that are used in more than one place, and which require additional set-up before they're actually used, you'll probably save a bunch of time overall. And your experience developing with your own controller and view classes will be like developing with Cocoa's.
I think the Apple guidelines sum it up nicely.
If you're writing a control that will be used in multiple applications and is completely generic, then creating a custom object is a good idea. You'll be able to visualize the look and set properties directly from Interface Builder.
If your control is limited to one application, or is tightly coupled with your data, then moving it into a custom object really won't buy you much.
It's not difficult to create a custom view, there are a lot of easy to follow guides out there.