I know "id" type, but what does id<Litigating> mean ?
#protocol Litigating
-(int) sue:( id<Litigating> ) someone;
#end
Think of Objective-C protocols as Java, C#, etc. Interfaces on speed.
This is a variable of any class, conforming to the protocol Litigation (this is as far as traditional OOP goes without jumping hoops):
id<Litigation> someone;
This is a variable of the class Company (and subclasses), that also conforms to Litigation:
Company<Litigation>* someone;
This is a variable of class Company, that also conforms to both Litigation and NSCopying**:
Company<Litigation, NSCopying>* someone;
id<SomeProtocol>
implies that this object implements SomeProtocol. It must be implementing all the required methods belonging to SomeProtocol.
It means that the parameter is not only of type id but also conforms to the Litigating (formal) protocol, cf. The Objective-C Programming Language.
Related
This question already has answers here:
Why Choose Struct Over Class?
(17 answers)
Closed 7 years ago.
I learn Swift from some time, I know the differences between structure and class. The main difference is structure is of value type and class is of reference type but didn't understand when to use structure instead of a class. Please explain it.
For example, In case of Protocols:
First, We have just a protocol of struct type:
protocol SomeProtocol{
func doSomeStuff()
}
Second, We make protocol of class type like this:
protocol SomeProtocol: class{
func doSomeStuff()
}
So, Please explain me, when we have to use protocol of struct type or of class type.
Firstly structs are passed by value (copied), and a class is passed by reference (copied just the memory address to the object).You may want to use structs for simpler types, because you get a free init for all the properties your struct has.And with protocols, the first one you can use it on class,struct and enum, the second you say that you only use that on classes,and you may want to put class if your protocol is a delegate or a data source,because you want the property(of the type of your protocol) weak to avoid the memory cycle. IMHO use classes for multi-scene apps because you don't need to take care to update value when you edited something in an another scene.
The protocol is not "of struct type" or "of class type", that is wrong terminology.
If you write SomeProtocol: class you make sure only classes can conform to that protocol, structs cannot. If you don't include the class both classes and structs can conform.
The docs (scroll down to "Class-Only Protocols") tell you that
You can limit protocol adoption to class types (and not structures or enumerations) by adding the class keyword to a protocol’s inheritance list. The class keyword must always appear first in a protocol’s inheritance list, before any inherited protocols.
Use a class-only protocol when the behavior defined by that protocol’s requirements assumes or requires that a conforming type has reference semantics rather than value semantics. For more on reference and value semantics, see Structures and Enumerations Are Value Types and Classes Are Reference Types.
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.
#interface ThreadsViewController : UIViewController <NSKeyValueObserving>
{
}
Error:Cannot find protocol declaration for 'NSKeyValueObserving'.
I'm using Foundation framework. Why do I have this error?
NSKeyValueObserving is an informal protocol:
An informal protocol is a category on NSObject, which implicitly makes almost all objects adopters of the protocol. (...) Implementation of the methods in an informal protocol is optional. Before invoking a method, the calling object checks to see whether the target object implements it.
You can not adopt an informal protocol using the angle brackets syntax, that is for formal protocols. With informal protocols, you simply implement the protocol methods. Your attempt to conform to the protocol NSKeyValueObserving in the #interface block:
#interface ThreadsViewController : UIViewController <NSKeyValueObserving>
is the reason why the compiler is complaining.
From Protocols:
Being informal, protocols declared in categories don’t receive much language support. There’s no type checking at compile time nor a check at runtime to see whether an object conforms to the protocol.
You should check the documentation for NSKeyValueObserving. In that you can find at top that in which framework resides. Just confirm that you are including that framework in your project.
Are you sure FoundationFramework is added to your project? If not, add it.
I have an Objective-C protocol:
typedef enum {
ViewStateNone
} ViewState;
#protocol ViewStateable
- (void)initViewState:(ViewState)viewState;
- (void)setViewState:(ViewState)viewState;
#end
I'm using this protocol in the following class:
#import "ViewStateable.h"
typedef enum {
ViewStateNone,
ViewStateSummary,
ViewStateContact,
ViewStateLocation
} ViewState;
#interface ViewController : UIViewController <ViewStateable> {
}
#end
I won't go too far into the specifics of my application, but what I'm doing here is typedefing an enumeration in a protocol so that the protocol's methods can take an input value of that type.
I'm then hoping to redeclare or extend that typedef in the classes that conform to that protocol, so that each class can have their own view states. However, I'm running into the following two errors:
Redeclaration of enumerator 'ViewStateNone'
Conflicting types for 'ViewState'
I'm ashamed to admit that my knowledge of C (namely typedefs) is not extensive, so is what I'm trying to do here, firstly, possible and, secondly, sensible?
Cheers friends.
It is neither possible nor sensible. This comes from the fact that typedefs and enums are basically just defines. (Well, not really, but for this purpose, they are.) If you need to do things like this, you might want to review your design (see below).
More info
typedef type newtype;
is (almost) equivalent to
#define newtype type;
and
enum {
ViewStateNone
};
is basically the same as
#define ViewStateNone 1
There are a few finer points withe regards to differences between the two, and the most compelling argument for using enums and typedefs is of course compile time checking of integer constants.
However; once an typedef enum {} type; has been seen, it cannot be unseen, and once it has been seen, its name is reserved for it, and it alone.
There are ways around all of this; but those are paths rarely traveled, and generally for good reason. It quickly becomes incredibly unmanageable.
As a solution, you might want to create a new class, MyViewState, which represents a view state and associated information, which could easily just be a wrapper around an NSInteger.
In closing: Review your design. I fear you might be doing something overly convoluted.
It's certainly not possible in the form you have it, for reasons that the errors fairly succinctly explain. An enum constant can only be declared once in any scope, and similarly a typedef.
Moreover, there's a bit of a conceptual difficulty with defining a type in a protocol that implementors can then redefine. The implementors should be conforming to the type, not adding to it. If the class needs to be able to determine its own set of values, the protocol must use a type that is general enough to hold all those that might be wanted. In this case you could use int or, probably more sensibly, something readable like NSString. You might also add another method to the protocol that will report back the values supported by the implementing class.
I have a class which is intended to be abstract. This means: When someone subclasses it, a few methods MUST be overwritten.
But on the other hand, those methods are not intended to be called manually from anywhere except inside the abstract class (the superclass of the subclass).
Must I declare these methods in .h anyways or can I just add comments in .h which say "you must overwrite -foo and -bar"? Or is there a better pattern to make abstract methods?
Related: Is there a way to create an abstract class in Objective C?
Objective-C doesn't actually have a way to declare a class as abstract. From Apple's Docs:
Abstract Classes
Some classes are designed only or
primarily so that other classes can
inherit from them. These abstract
classes group methods and instance
variables that can be used by a number
of different subclasses into a common
definition. The abstract class is
typically incomplete by itself, but
contains useful code that reduces the
implementation burden of its
subclasses. (Because abstract classes
must have subclasses to be useful,
they’re sometimes also called abstract
superclasses.)
Unlike some other languages,
Objective-C does not have syntax to
mark classes as abstract, nor does it
prevent you from creating an instance
of an abstract class.
The NSObject class is the canonical
example of an abstract class in Cocoa.
You never use instances of the
NSObject class in an application—it
wouldn’t be good for anything; it
would be a generic object with the
ability to do nothing in particular.
The NSView class, on the other hand,
provides an example of an abstract
class instances of which you might
occasionally use directly.
Abstract classes often contain code
that helps define the structure of an
application. When you create
subclasses of these classes, instances
of your new classes fit effortlessly
into the application structure and
work automatically with other objects.
So to answer your question, yes, you need to place the method signature in the header, and should implement the method in the base class such that it generates an error if called, like the related question's answer states.
You can also use a protocol to force classes to implement certain methods.
However you choose to implement the base class, clearly document in the header, as well as in your documentation, exactly what the class assumes and how to go about sub-classing it correctly.
Whenever possible write your code so that improper implementations fail to compile. If you cannot do that then you should try to generate a runtime error (at the very least in a debug build) if the subclass is not written correctly. Do not rely on comments because people will not read them.
You must declare your "protected" and "abstract" methods in a header file, but you can use separate categories to clearly indicate their purpose and intended use.
#interface MyBaseClass : NSObject {
}
- (void)foo;
#end
#interface MyBaseClass(ProtectedMethods)
- (void)bar;
#end
#interface MyBaseClass(AbstractMethods) // Subclasses must implement
- (void)internalBar;
#end
You can put everything in a single header, or you could put your protected and abstract declarations in a separate "protected" header, say MyClassProtected.h, meant to be included only by your subclass implementations. It depends on how badly you want "hide" your protected methods.
Your base class can log, assert, or throw when an abstract/pure-virtual method is called.
As other people have said, Objective-C does not support pure virtual classes.
You can enforce pure virtual behaviour at runtime though. The cleanest way to do this is by using the Objective-C runtime's _cmd and NSObject's -doesNotRecognizeSelector:
- (void)iMustBeImplementedInaSubclass;
{
[self doesNotRecognizeSelector:_cmd]; // Pure virtual
}
As ben says you are probably better served by using a protocol to get your API design right.