Is there a Swift attribute, such as #nonobjc designed for protocols? - swift

I want to write a PAT and I don't care about Obj-C interoperability. The #nonobjc attribute sounds perfect but its designed for variables and methods only.
Anything similar for hiding protocols from Obj-C?

You seem to be misunderstood what the #nonobjc attribute is for:
From the docs:
nonobjc
Apply this attribute to a method, property, subscript, or initializer
declaration to suppress an implicit objc attribute.
If you scroll further down the page, it tells you what will have an implicit objc attribute on them:
The compiler implicitly adds the objc attribute to subclasses of any class defined in Objective-C. However, the subclass must not be generic, and must not inherit from any generic classes. [...] The objc attribute is also implicitly added in the following cases:
The declaration is an override in a subclass, and the superclass’s declaration has the objc attribute.
The declaration satisfies a requirement from a protocol that has the objc attribute.
The declaration has the IBAction, IBSegueAction, IBOutlet, IBDesignable, IBInspectable, NSManaged, or GKInspectable
attribute.
This does not include protocols, so protocols are never implicitly exposed to Objective-C. This means that you don't need the nonobjc attribute on protocols to suppress implicit objcs on protocols. Protocols, by default, are not exposed to Objective-C, unless you mark them with #objc.

Related

Why do I have warning "Redundant constraint 'Self' : 'AnyObject'"

I have updated my Xcode to 12.5. And now I can see next warning:
"Redundant constraint 'Self' : 'AnyObject'"
What does cause this warning?
(RouterType has to be available only for classes.)
AnyObject requires the member that conforms to the protocol to be a class, but you already marked it #objc, and in Objective-C only classes can conform to protocols.
Thus requiring AnyObject is redundant and you can remove it.
The reasoning behind this warning is flawed, in my view. The terms are not synonyms.
AnyObject makes this a class protocol.
#objc exposes the protocol to Objective-C.
That’s two different things. The latter may logically imply the former, in that only a class protocol can be exposed to Objective-C; but that doesn’t make it redundant. (The type declaration in let s : String = "x" is redundant logically, after all, in just the same way — the compiler doesn’t need it — but there’s no warning.)
Apple has made a wrong decision here. I intend to file a bug.

why do I have to mark both the protocol & contained optional functions in a swift protocol as #objc?

I have discovered some inconsistency when declaring optional functions in a protocol. While declaring a function in a protocol optional, I have to mark both the protocol and the optional function as #objc. I then looked up the documentation for UICollectionViewDataSource and found that there was no such requirement over there for declaring optional functions.
I have tried to confirm to NSObjectProtocol but the compiler still requires me to mark the protocol as well as the optional function as #objc. Can someone please enlighten me regarding the same?
UICollectionViewDataSource is imported from ObjC. The auto-generated Swift header doesn't insert #objc on every element. It is common for these headers to be invalid Swift (for example, they define structs and classes without implementations, which isn't valid Swift).
When you're writing Swift (rather than looking at auto-generated headers), you need to tell the compiler that it needs to bridge certain things to ObjC, and you do that with #objc. Imported ObjC doesn't have to be bridged.
If you want to make optional function in a protocol then you have to declare in this manner
#objc protocol MyOptionalProtocol {
#objc optional func optionalFunction()
}

What is the motivation for requiring "override" on an initialiser that has the same signature as one in a base?

For methods it is clear to me that accidentally overriding a method could have bad consequences, so requiring developers to be explicit about it with the "override" keyword seems like a good idea.
However, as initialisers are invoked on a type (as it were) instead of on an object, I don't understand what overriding means in this context nor what kind of mistakes the requirement for the "override" keyword on initialisers is preventing.
I find the override modifier to provide only a convenience and safety function of expressing the intent of a developer to either override an existing member of a class (when the modifier is present) or to introduce a new one (when the modifier is missing) so the compiler can perform the corresponding compile-time checks and inform the developer if the expressed intent could not be implemented (because there is nothing to override or because there is a signature collision with a member defined in one of the base classes).
You can argue that there is a difference between overriding a virtual member or providing a distinct statically dispatched initializer replicating the signature of an initializer of the base class. Technically, yes; but not semantically. Semantically you may still want to replicate the signature of an initializer of the base class, and the compiler is ready to perform the corresponding compile-time signature checks.
The Swift Language Guide in the chapter "Initialization" under the title Initializer Inheritance and Overriding says:
When you write a subclass initializer that matches a superclass designated initializer, you are effectively providing an override of that designated initializer. Therefore, you must write the override modifier before the subclass’s initializer definition. ...
As with an overridden property, method or subscript, the presence of the override modifier prompts Swift to check that the superclass has a matching designated initializer to be overridden, and validates that the parameters for your overriding initializer have been specified as intended.
From this excerpt the role of the override modifier indeed appears to be small — to verify the intent of a developer to match a signature from the base class or not.

Swift: Using getter with no value

What is the benefit of using a getter with no value. For example:
protocol xyz:Class{
var uuid:UUID{get}
}
I'll really appreciate your thoughts.
The code in your question is declaring a protocol. A protocol is basically a contract. It provides no functionality.
Your protocol's contract is stating that whatever conforms to the protocol must, at a minimum, provide a getter for a variable named uuid with a type of UUID.
The protocol itself does not provide the getter so it does not return a value. The class/struct/enum that conforms to the protocol will provide a value from the getter. This same class/struct/enum may also (if desired) provide a setter for the uuid variable as well. The protocol only states there must be a getter but it does not preclude the possibility of a setter.
The Protocols chapter in the Swift book shows examples and provides much more information on this. Specifically, the Property Requirements section covers protocol properties.

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.