Why create accessor methods when I can just use KVC? - cocoa

I am trying to get my head wrapped around "key-value coding".
Apple's docs say:
This document describes the NSKeyValueCoding informal protocol, which
defines a mechanism allowing applications to access the properties of
an object indirectly by name (or key), rather than directly through
invocation of an accessor method or as instance variables.
Few thing are confusing me
Accessor methods are automatically generated for properties, and provide several benefits like memory management, custom validations, etc. When we access a property without the accessor methods as the Apple doc says, does that mean we are losing the benefits of accessor methods?
If KVC is so good and it reduces code, why should I use accessor methods, or why are accessor methods still around?
I have never seen in any tutorial or books, or code on GitHub using KVC. Why is it not adopted that widely?

No, it just means that you aren't explicitly calling the accessor in your code. The accessor is called for you by the KVC implementation.
KVC doesn't necessarily reduce code, rather it allows a different way of interacting. It allows more runtime flexibility and it can allow the use of key paths. You shouldn't look at it as a full replacement, just as an alternative which is appropriate in some cases.
It is used widely, you need to look for calls to valueForKey:, setValue:forKey: (the methods of the protocol - there are many more than just these couple).

Related

What is the purpose of protocols if all methods are optional?

I understand what purpose protocols serve (to have a type conform to a set list of methods or/and properties), but I don't understand what the purpose is of a protocol with all optional methods. One example would be UITextFieldDelegate.
If all methods are optional in a protocol, why would you conform to the protocol instead of just writing the methods from scratch in your class? I don't see what the benefit or purpose of conforming to the protocol is in this case.
Are the optional methods there just as suggestions of functionality that could be implemented?
Historically, for delegates and data sources in Cocoa, informal protocols were used. Informal protocol was implemented trough a category for NSObject class:
#interface NSObject (NSTableViewDelegate)
- (int)numberOfRowsInTableView:(NSTableView *)tableView;
// ...
#end
Later, optional methods in protocols were introduced. This change leads to better documenting of class responsibilities. If you see in code, that class conforms to NSTableViewDelegate, you suspect that somewhere exists a table view, that managed by instance of this class.
Also, this change leads to stronger checks in compile time. If programmer accidentally assign wrong object to delegate or dataSource properties, compiler will warn.
But your assumption is also correct. Optional methods are also suggestions for possible functionality.
By default, all methods in a protocol are required. Each method has to be marks as optional if the nor required for everything to function correctly.
If all methods are optional in a protocol, why would you conform to the protocol instead of just writing the functions from scratch in your class?
Conforming to a protocol allow your class to tell another object the methods it has without the other object needing to know about your class. This is really useful when using Delegation as it allows the delegate to decide what information they wish to receive/provide to another class.
For example,the UIScrollViewDelegate protocol only defines optional methods. Lets say we have a class Foo that we want to know when things change with a UIScrollView.
If we decided to throw that protocol away and implement the functions from scratch, how would we tell UIScrollView which methods we implement and which methods to call when certain event occur? There is no good way it could find out. When UIScrollView was built, it didn't know about Foo so it can't know what methods it implements. Also, Foo has no way of knowing what methods can be called on it by the UIScrollView.
However, when UIScrollView was built, it did know about UIScrollViewDelegate. So if Foo conforms the the UIScrollViewDelegate protocol, there is now a common definition that both Foo and UIScrollView can follow. So Foo can implement any methods it cares about, like scrollViewDidScroll: and the UIScrollView just needs to check if the delegate implemented the methods in UIScrollViewDelegate.
The protocol establishes a contract for the interface between one object and another. The fact that the methods are optional simply says that you don't have to implement that particular method, but you can if your app calls for it.
Generally, if you're conforming to a protocol for which all of the methods are optional, though, you're doing that for a reason, namely that you plan on implementing one or more of those methods. Just because all of the protocol's methods are optional doesn't mean you will not implement any of them, but rather simply that you can elect which are relevant in your particular situation.
For example, consider the UITextFieldDelegate protocol. You'd generally conform to that because you want to specify, for example, whether certain characters should be allowed to be inserted into the text field or what to do when the return key is pressed. Sometimes you only want to implement the former. Sometimes you only want to implement the latter. Sometimes you do both. But just because you choose to implement one or the other doesn't mean you necessarily want to do other one (but you can if you want). Frankly, though, if you really didn't want to implement any of the methods, you probably wouldn't even bother to specify the delegate of the text field, nor bother to specify that you're conforming to the protocol.
Bottom line, the protocol that consists solely of optional methods basically says "if you need it, this is the documented interface for the methods you may elect to implement". The protocol still is very useful to establish the possible interfaces, but doesn't force you to implement those methods you do not need.

Swift: Do protocols even have a real purpose?

I'm wondering why protocols are used in swift. In every case I've had to use one so far (UICollectionViewDelegate, UICollectionViewDataSource) I've noted that they don't even have to be added to the class declaration for my code to work. All they do is make it such that your class needs to have certain methods in it so that it can compile. Beats me why this is useful other then as a little post it note to help you keep track of what your classes do.
I'm assuming I'm wrong though. Would anyone care to point out why to me please?
A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. The protocol doesn’t actually provide an implementation for any of these requirements—it only describes what an implementation will look like.
So it's basically an interface, right?
You use an interface when you want to define a "contract" for your code. In most cases, the purpose of this is to enable multiple implementations of that contract. For example, you can provide a real implementation, and a fake one for testing.
Further Reading
Protocols
What is the point of an Interface?
It allows flexible linkage between parts of code. Once the protocol is defined it can be used by code that doesn't need to know what will be done when the methods are called or exactly what object (or struct or enum) is actually being used. An alternative approach could be setting callbacks or blocks but by using a protocol as complete set of behaviours can be grouped and documented.
Some other code will typically create the concrete instance and pass it to the code expecting the protocol (sometimes the concrete instance will pass itself). In some cases neither the implementation of the code using it need to be aware of each other and it can all be set up by some other code to keep it reusable and testable.
It might be possible to do this in some languages by duck typing which is to say that a runtime inspection could allow a object to act in such a context without particular declaration but this is probably not possible to do at compile time in all cases and it could also be error prone if worked out implicitly.

What features does mogenerator provide?

I've been using mogenerator for a while now, and while there is a reasonable Getting Started Guide and a Stack Exchange article on the command line options, I haven't found a good guide for all of the functionality it provides.
In short: what, above and beyond the classes that Core Data provides for you, what does mogenerator actually generate?
(Frankly, I kept finding little pleasant surprises in the headers/implementations that I didn't realize were in there and I decided to step through the mogenerator templates and code and document what I found in a Stack Exchange Q&A. I'd love to see additional answers and edits, however. )
In addition to its core feature of a two class system, mogenerator helps you by automatically implementing a number of best practices regarding Core Data in your machine header and implementation files.
Property Accessors
Methods to access the attributes of your Entities are the core of what mogenerator generates. But there are some nice features implemented in the accessors above and beyond what the out of the box Xcode class generator provides to you.
Scalar Accessors
Xcode's built in generator gives you the option of "use scalar properties for primitive data types". This option gives you choice of having Xcode create properties with NSTimeIntervals instead of NSDates for date types, BOOLs instead of NSNumbers for boolean types, and int16_t (or similar) rather than NSNumbers.
I find this infuriating because most of the time I prefer the primitive types, but not for NSDates which are much more useful than a NSTimeInterval. So Core Data is giving me the choice of objects, in which case I will be constantly unboxing stuff and making stupid mistakes like if(myBooleanAttribute) (which is always YES because myBooleanAttribute is a NSNumber, not a BOOL). Or I can have scalars, but in that case, I get NSTimeIntervals that I'll always have to convert to NSDates. Or I can hand edit all of the generated files by hand to give me my desired mix of NSDates and BOOLs.
On the other hand, mogenerator provides you with both options. For example, you will get both a myBooleanAttribute getter that gives you an NSNumber (for easy storage in an NSArray) and a myBooleanAttributeValue getter that gives you an actual BOOL. Same with integers and floats. (Mogenerator does not generate NSTimeInterval accessors: only NSDates.)
Typed Transformable Properties
If you have a transformable property, you can set a specific UserInfo key ( attributeValueClassName ) in the attribute that will specify the class that your property will return/accept. (And it will properly forward declare the class etc.) The only place I found this documented was on Verious.
In contrast, the Xcode code generator will only type these transformable attributes as id types.
Validation Declaration
While mogenerator does not automatically generate any validation methods, it does include the proper signature as a comment in the machine h file. The seems to largely be for historical reasons, but it does mean that it is easy to copy and paste the signature if you decide to implement it in your human file implementation. (I wouldn't actually uncomment the declaration as you aren't supposed to call validation directly.)
Primitive Accessors
Core Data already provides you these accessors to the primitive values, but for some reason doesn't include them in its Xcode generated headers. Having mogenerator include them in its header files makes it much easier to access a primitive value.
Fetched Properties
mogenerator will generate accessors for fetched properties. As far as I can tell there is no way to have the Xcode generator do this.
Helper methods
Automatic NSFetchedResultsController generation
If you have a to many relationship in your Entity and you pass --template-var frc=true into mogenerator, mogenerator will automatically generate a method to create a fetch request for the child objects associated with a parent object. It even automatically generates a unique cache name, and isolates everything inside an #if TARGET_OS_IPHONE preprocessor macro.
Even if this doesn't fit your particular needs, it is a great example of how the templates can be extended.
+fetchMyFetchRequest:moc_
If you like defining your fetch requests in the model, this is a lot better way to retrieve them than hardcoded strings.
-MyEntitySet
Mogenerator uses the magic of KVC to give you a NSMutableSet proxy into your relationships.
+entityName
Need to provide a entity name to a NSFetchRequest or other Core Data method? It's easy to avoid hard coded strings by using this simple method that returns the name of the entity as an NSString.
+insertInManagedObjectContext: and entityInManagedObjectContext:
Another way to avoid hardcoding entity names is to use these helper methods.
Typed object ids
Each of your headers and implementations also includes a MyEntityID class. They are empty interfaces and implementations that merely subclass the NSManagedObjectID class. Also, each model class has a helper method called objectID that overrides the standard objectID method in NSManagedObject. The helper method does nothing but cast the superclass's return value to the MyEntityID type.
The net result: the compiler can catch your mistakes if you ever accidentally interchange your object ids from different entities.
Miscellaneous
Subclassing a Custom Superclass
One of the command line options is --base-class: which allows you to specify a base class that all of your generated classes will inherit from. This is very useful, either so that you can have a base class where you define convenience methods (which, given Core Data, you probably should) or so you can use an off the shelf Core Data toolkit like SSDataKit (or both).
includem
A simple little thing, but if you specify a --includem argument, mogenerator will generate a header file that includes all of your model header files. Convenient if you want to include all of your headers in a PCH, or something some other standard header you include.
Const Definitions of All Attributes, Relationships, Fetched Properties
An extern declaration of a struct is included in the header that has an NSString defined for every attribute and relationship defined in your Entity. This allows you to define predicates and other parameters, without baking the names of your entities into your strings. For example,
req.predicate = [NSPredicate predicateWithFormat:
#"(%K == YES) AND (%K <= %#)",MyObject.favorite, MyObject.availableDate, [NSDate date]];
(This type of struct used for "namespaced" constants is described My Mike Ash on his blog
const Definitions of User Info Keys/Values
Similarly an extern declaration of a struct is defined in the header that includes the keys as members of the struct, and the values as a values. i.e.
NSLog(#"User info for key my key is %#",MyObjectInfo.mykey) //will log "myvalue"
Alternate Templates
One of the interesting things about mogenerator is that in building mogenerator its author (Wolf Rentzsch) has basically built a generic parser and templating engine for the xcdatamodel files produced by Xcode. So you don't need to use the mogenerator templates. You can provide your own with a simple command line argument. There are lots of user contributed templates on the GitHub site.
In fact, you don't even have to use Core Data. Many of the contributed templates allow you to generate a series of ordinary NSObject model classes based on the data model. (So called PONSOs: "plain old nsobjects"). Want to use the data modeler in Xcode, but some other persistence mechanism? mogenerator can help you there.
You don't even need to generate objects at all: another interesting submitted template just provides a diff of two different model versions.

Why does Cocoa binding use both KVC and KVO and not just KVC?

As a newbie to Cocoa and Objective-C I have a rudimentary understanding of KVC and KVO. However with respect to Cocoa Bindings (as covered in the Apple document titled "Cocoa Bindings Programming Topics" see figures 8-10) I'm unclear why they are depicting using both KVC and KVO, when it seems that KVO would be sufficient. KVO's ObserveValueForKeyPath:ofObject:change:context can provide the old and new values so why is KVC mechanisms needed? Note, I see how KVO decouples objects, but so does KVC.
The example Apple gives (figures 8-10) depicts a Window containing a slider and a text input control to visually represent and allow user interaction for setting&viewing "temperature", a Controller object, and a Model Object with a temperature property. So put another way my question is why not just have a bi-directional KVO relationships between the 2 controls and the controller (each registers with the other as an observer), and bi-directional KVO relationships between the Model Object and the Controller? Why is KVC needed?
The long-winded docs are confusing you.
All this does is about code-reusability.
(1) Provide a standard way to declare and manage properties.
(you can do it manually the old way with ivars and setters and getters, but property synthesis gives it to you for free)
You cannot Observe the Key Value Pairs reliably unless they follow a convention.
The convention is KVC. Following that is being KVC compliant.
(2) Provide a highly reusable and generic way for objects to receive notifications about changes to a property in another object. This is KVO.
KVO is the ability to generically code notifications based on changes in properties that are KVC compliant first.
(3) Bindings & Core Data. Both technologies are built on KVC and KVO to make this all work in as generic a way as possible.
It is also quite similar conceptually to ORMs like Active Record and Ruby on Rails.
The magic starts with KVC.
KVC enables a simple KVO mechanism.
KVO + KVC make Bindings and Core Data possible and easy.
They also provide a lot of syntactic sugar and wacky conveniences.
You can treat the interface to KVC compliant objects as a dictionary or an array.
Then all the patterns fall into place.
You can still have other bi-drectional observer patterns.
Delegation (setting eachother as or sharing a delegate) and Notification (via NSNotification), or even simply messaging other objects (likely bad tight coupling if this is your pattern everywhere, leading to these other patterns being created)
These are not wrong, but have some trade-offs.
Notifications can be spaghetti code at times. Like all callbacks, you end up with something like goto sometimes. However, it isn't necessarily as tightly coupled to a specific property of a specific object like KVO. It is just waiting for a potentially very general notification that could contain a lot of different things. However, by its nature, Notifications tend to be more use-case specific, and easy to apply to custom scenarios.
KVO as-a-specific-technology is built on KVC conventions, and does not work without them.
It makes some very basic, common boiler-plate code & tight coupling easier to create.
A few have tried in the comments, he's my go:
KVO is essentially built on top of KVC - when a KVC compliant property is changed if there is an observer then the KVO machinery kicks in, constructs the info dictionary as needed, and sends the message to the observer(s).
If they question is why was it done this way and why not another then that is a different question. KVO needs to plug into something - you can't just observe changes to a variable (memory location) in a simple way[*]. A property, having a setter & getter, is a place things such as KVO can hook in. And properties follow the KVC pattern and there is already machinery to support that... But that doesn't mean KVO has to depend on KVC, other implementations strategies are undoubtedly possible.
HTH at little.
[*] entering the debugging mode and deploying watchpoints is not "simple" in this context!

Is using Clone() a bad programming practice if doing on heavily loaded objects?

We have a class that is more like a template (with lot of properties and overridden methods). I need to make many objects of that class type. Can I use clone() to create objects with specific settings if I have one object created? I know I need to override the Clone method. Is the performance going to take a hit by using Clone()?
Cloning an object as a way of creating new objects is not necessarily the cleanest method of creating objects. It is better to use constructors or factory methods (which call constructors).
You may be interested in using a factory or builder pattern. Or if you are worried about the memory overhead of a large number of similar objects, take a look at the flyweight pattern.
Clone in itself is not bad practice, its generally shallow. BUt i think you want to be using a pattern. More than likely Prototype Pattern is your solution.
The clone you are doing is really a cookie cutting of your prototype.
The link i sent is from DO factory and has code samples for you.

Resources