Why do we need to use id type for creating delegate object for protocols in Objective C? I couldn't find proper answer from google
Because a delegate can be implemented by any type of object.
Ex : UIViewController, UIView, NSObject class can all implement the same protocol, so the delegate can't know the type, so it's set to id.
Related
I can't solve next problem: I have 2 applications which talk to each other using Distributed Objects. Suppose application A call - (void)updateState:(State *)state method from application B.
#interface State : NSObject <NSCopying, NSCoding>...
When updateState: method called in B app I have NSDistantObject representing sended object instead of State object. In Friday Q&A I found that if object conforms to NSCoding protocol the object should be 'sended' instead of proxy, but, I still receive a proxy. I don't find any info about it in Apple Documentation. Maybe someone does know how can I send object instead of proxy and how Distributed Objects system decide when serialize and send an object and when a proxy?
I found it! Also, you should implement - (id)replacementObjectForPortCoder:(NSPortCoder *)coder in object, which you want to pass through. More about this method you can read in Apple documentation.
Mystical isBycopy and isByref of NSPortCoder, which Apple refs to documentation, but in last is no info, determined by bycopy and byref method parameters keywords. More about this keywords you can read here.
In Aaron Hillegass' Cocoa Programming for Mac OS X, the Raiseman application connects a button in Interface Builder (IB) to an NSArrayController with sent action -remove:. In the MyDocument class he implements two KVC methods:
- (void)insertObject:(Person *)p inEmployeesAtIndex:(int)index;
- (void)removeObjectFromEmployeesAtIndex:(int)index;
When this button is pressed, the -removeObjectFromEmployeesAtIndex: method is called and the currently selected Person (Model) object is removed from the array.
How does the remove: method used in IB cause the -removeObjectFromEmployeesAtIndex: method to be called?
How do I reproduce this effect with an NSTreeController?
If you want a simple built-in option, then it's only going to create an instance of the class you specified in IB. To create another instance, you're going to need to code it yourself. You should have all the information you need from the Tree Controller to insert the new class into the proper place in the hierarchy. Some diligent searching should give you the code you need.
To attempt to help you understand how the NSArrayController mechanism works, I'll explain the best I can from my knowledge of Objective-C and the runtime. Objective-C is a very dynamic language, and you can dynamically call selectors (methods). Since the NSArrayController knows the name of your class (e.g. "Employee"), its internal implementation probably looks something like the following (or easily could):
NSString *removeSelectorName = [NSString stringWithFormat:#"removeObjectFrom%#sAtIndex:",
self.objectClassName];
SEL removeSelector = NSSelectorFromString(removeSelectorName);
[dataRepresentation performSelector:removeSelector
withObject:[NSNumber numberWithInt:self.selectionIndex];
There are examples of this elsewhere in KVO, as with the +keyPathsForValuesAffecting<Key> method (documentation here), which describes which keys cause another key to be updated. If your key is named fullName and it updates whenever the first or last name changes, you would implement this in your class:
+ (NSSet *)keyPathsForValuesAffectingFullName {
return [NSSet setWithObjects:
#"firstName",
#"lastName",
nil];
}
Further searching (and this question) turned up this documentation page, which explains the semantics of how that method gets called.
I got answer about Foundation magic for this question: What's the most *simple* way to implement a plain data object which conforms key-value-observing?
What's the magic? How it work internally? Because it's dangerous using framework which I can't understand its internal behavior, I want to know its behavior. Currently, I cannot understand how it work without any method definitions.
Apple's documentation describes how KVO is implemented internally.
The gist of it is that when you register an observer on an object, the framework dynamically creates a subclass of the object's original class, and adjusts the object to appear as an instance of this new dynamic class. You can see this if you inspect an object in the debugger after it has had an observer registered.
This new class intercepts messages to the object and inspects them for those matching certain patterns (such as the getters, setters, and collection access).
In a nutshell: Objective-C 2.0's #property declaration creates accessor methods for the named property, so there are method definitions. #property is just a shorthand way to define them which avoids a lot of repetitious boilerplate code.
When you observe a property, a private subclass is created which implements accessors that call the appropriate notification methods before and after changing the property value. A technique known as "isa swizzling" is then used to change the class of the observed object.
#interface ClassB <ClassADelegate> : ClassA
id <ClassBDelegate> delegate;
#end
As the code says, ClassB subclasses from ClassA and handles the formation protocol of Class A. However, the variable "delegate" will be duplicated. (ClassA also has "delegate")
In fact, it can be done without subclassing, but it seems the code is cumbersome, i.e., to use a variable/function of ClassA, I need to write [[ClassB classA] doSomething] instead of [classB doSomething], where doSomething: is a function of ClassA.
Are there any tidy way for me to do that?
In looking at the sample you posted, ClassB conforms the ClassADelegate protocol and ClassB then has a delegate object that conforms to ClassBDelegate. If ClassB conforms to ClassADelegate and is also a ClassA subclass, I'm curious why the ClassADelegate methods are not just part of ClassA to begin with.
So, I would rethink the architecture of this setup and try to keep your model objects and delegates separate, which is the point of the delegate pattern in the first place. If that doesn't make sense for your application, some more concrete information about what your subclassing is meant to accomplish would be helpful.
In doing some work today it occurs to me that Apple does use delegation and subclassing, but definitely not in the way that you've proposed. Have a look at the NSTextField and NSControl classes. NSTextField subclasses NSControl of course and has its own delegate methods but NSControl also has a set of delegate methods. But NSTextField does not conform to the NSControl's delegate protocol (which in fact does is not specified as a protocol anyway).
I'm writing a Cocoa API for a project and the API takes a delegate. The protocol that I came up with declares all the methods as optional, but why would I do that instead of just documenting the delegate methods in a header file and taking a plain id as a parameter?
For the benefit of your users. If the object takes delegates conforming to some protocol and they pass something else in, the compiler can tell them. That isn't possible if you take an id and use a category as the delegate method interface.
Because having "all of these methods" optional isn't quite the same as permitting "anything you care to send".
It also produces code that is more usable in the IDE. For example if I'm looking at
#interface MyController : NSObject <FooBarDelegate> {
}
#end
I can command+double click in Xcode to jump to the definition of FooBarDelegate. With a category there's no formal declaration of intent to be a delegate.
Also, #required can be a problem for future plans with regard to backward binary compatibility and a new preferred method signature.