Calling protocol methods on super - iphone

Can I call a protocol method from a child on its super class, even though the super class supports the protocol privately?
Let's say I have a Class A which privately conforms to UIGestureRecognizerDelegate protocol. Class B inherits from Class A but when I tried to call [super gestureRecognizerShouldBegin:gestureRecognizer]; I get an error.
Any idea?

The UIScrollViewDelegate doesn't declare a method named gestureRecognizerShouldBegin:gestureRecognizer:.
But generally speaking, yes, its possible to call methods declared in protocols that the super class implements, but keep in mind that methods marked with #optional in the protocol aren't guaranteed to be implemented (you can check this via the respondsToSelector: method)

Related

access control on protocol implementation init

Trying to enforce an access control for a protocol that will be implemented by a singleton class.
I would like the class to have a fileprivate init, is there a way to enforce this behaviour?
Since a protocol is not a class i cannot put the init in the protocol extension.
According to Apple docs:
The access level of each requirement within a protocol definition is automatically set to the same access level as the protocol. You cannot set a protocol requirement to a different access level than the protocol it supports. This ensures that all of the protocol’s requirements will be visible on any type that adopts the protocol.
Link Protocol docs
EDIT: I have misread the question a bit.
If I understood OP's clarification, the only way I know at the moment to ensure that class is singleton is to mark its init method as private or fileprivate.
For my simple singleton with only static methods I have this:
private init() {
}

Set a generic class as a delegate in swift

I have a class XMLUtil, that wraps some xml parsing functionality. The class has one generic parameter T. The class also acts as the NSXMLParserDelegate to the NSXMLParser delegator.
class XMLUtil<T>: NSObject, NSXMLParserDelegate{
...
...
init(){
parser = NSXMLParser(data: NSData)
parser.delegate = self
parser.parse()
}
...
...
//delegate method implementations
}
The problem:
When my XMLUtil class is a generic class, the delegate methods never get called. They do however, when I implement the XMLUtil class without generic parameters
These two questions seem to be of similar nature
Swift Generic class as delegate
NSURLConnection Delegate Methods Not Called In Generic Class
Is there anything in the documentations that would explain this behavior? Is this intended or is it a bug?
When my XMLUtil class is a generic class
But Objective-C knows nothing of generic classes. So there is no way to show your XMLUtil class to Objective-C. Thus, it cannot serve as NSXMLParser's delegate; NSXMLParser is an Objective-C class and cannot see your XMLUtil class if it is generic.
One easy way to see this is to try to mark your XMLUtil class as #objc. You will fail; the compiler will stop you. There is no way to show this class to Objective-C.

Superclass vs Protocol in Swift?

I've never worked with objective C but have a fair bit of experience with C++.
What exactly is the difference between a superclass and a protocol in objective C? I read that a protocol is essentially a pure virtual class, but is that it? Is a protocol simply a specific type of superclass?
A protocol is a contract a class is going to conform to. When a class conforms to a protocol it tells the compiler that it will implement all the methods and all the properties declared in the protocol.
In Objective-C the class additionally needs a superclass. In a lot of cases this is NSObject. The superclass implements already a lot of methods (like isEqual:). A protocol never implements any methods or defines any property.
A protocol tells which properties/operations a class must implement. A superclass implements them and you can add your own stuff on top.
A protocol defines a set of method definitions that a class or struct must implement, very much like a Java interface.
A superclass is the class from which a given class inherits its method definitions, the implementation for those methods, and the instance and class properties.

implementing protocol methods in objective-c

If I have an protocol (say UIPickerViewDataSource) and I implement its required methods, do I need to declare those methods in the header file of my class?
At the moment I'm not doing so and I get a warning of incomplete implementation (although everything works fine). If I do add the required methods in the then I don't get such warning:
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
Is this the correct behaviour? Is it really necessary to add the declaration for required protocol methods in the header file of my class?
No, you don't. Declaring that the class implements that protocol and implementing the methods is enough. You could still declare them in the header for documentation purposes, though.
The correct way is to declare that your class implements the protocol. If for instance your class is called LordSandwichViewController, then your class interface must look like this:
#interface LordSandwichViewController : UIViewController <UIPickerViewDataSource> {
{
}
So you don't declare the protocol methods in your class interface, only the protocol.
Incomplete implementation warnings tell you that you are not implementing all the required methods you are either:
Defining in your header.
Declaring a method required by a protocol you're conforming to.
Look at what methods it's expecting, and implement those.

Why does adding a Swift protocol in some situations not require all the normally required methods?

For example, these are valid and will compile without (all) protocol stubs
public class ViewController: UIViewController, SFSpeechRecognizerDelegate {
}
class BLEController: CBCentralManager, CBCentralManagerDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
}
}
Edit: Solved! Creating a class without inheriting from UIViewController or CBCentralManager still does comply with the delegate protocols, but it does not comply with NSObjectProtocol. It just seems to be that I'm attempting to use the frameworks in an unintended way.
Why does my code compile without fulfilling all the protocol requirements?
What you are seeing here are optional protocol requirements. They are here because Swift code needs to interact with Objective-C, and Objective-C has them.
All methods except centralManagerDidUpdateState declared in CBCentralManagerDelegate are optional, from here:
The only required method is centralManagerDidUpdateState(_:); the central manager calls this when its state updates, thereby indicating the availability of the central manager.
And SFSpeechRecognizerDelegate, only contains one optional method, from here:
Use this protocol's optional method to track those changes and provide an appropriate response.
why does the code not compile if you remove the superclasses then?
This is because both of those protocols in your question also inherit from NSObjectProtocol, so they actually also have the additional requirements of NSObjectProtocol. UIViewController and CBCentralManager both inherits from NSObject, so they satisfy the NSObjectProtocol requirements, but your Swift class without a superclass doesn't.
Protocols with optional requirements don't have to inherit from NSObjectProtocol though. It's just that most of them are that way in the framework. You can for example do:
#objc protocol Foo {
#objc optional func foo()
}
class FooClass : Foo {
// compiles fine!
}
It compiles without needing the protocol stubs because all the requirement is optional. Check within the declaration of SFSpeechRecognizerDelegate it has only one requirement for a method called availabilityDidChange and you can see that it's optional from the keyword given at the beginning of the function.
In the second case, the class you have created doesn't inherit from NSObject but the first one does because it's a sub-class of UIViewController which in-turn is a sub-class of NSObject.