I'am using a third-party framework that provides a class whose instances only have properties. In my app, I'd like to add an extra property to this instances. What the appropriate way to do this would it be for this scenario?
a) Extending the framework's class in my app
b) Creating a subclass of the framework's class and define the new property I need
Thanks in advance
It's
b)
because adding (stored) properties in a class extension is not supported.
There are two important rules for using extensions:
Extensions can add new functionality to a type, but they cannot override existing functionality
Extensions can add new computed properties, but they cannot add stored properties, or add property observers to existing properties
It depends on what is the behaviour you are expecting to achieve.
Extending: You can only add new methods and computed vars, but you will achieve seamless effort in your code. the new functionality is available anywhere without adding new classes in your code
Subclassing: You can add new vars and override function but there is a bigger footprint in your code. You will need to use that specific subclass throughout your project.
I guess it is more of a design question.
My suggestion: if the entire project needs this new behaviour use extensions, otherwise subclass.
Related
Many CocoaPod and native iOS libraries use protocols that they name either CustomClassDelegate or CustomClassDataSource as a means to do some setup or customization. I was wondering when I should use this programming model, because it seems like I could accomplish much of this with properties.
Example
If I define a custom class called SmurfViewController that has a SmurfLabel, is it better practice to store the smurfLabel as a private property and have a public computed property called smurf that looks like this:
private var smurfLabel = UILabel()
public var smurf: String {
get {
return smurfLabel.text
}
set(text) {
smurfLabel.text = text
}
}
or should I define a SmurfDataSource that has a public function that looks like this:
func textForSmurfLabel() -> String {
return "smurfText"
}
When should I use what here?
You should just use a property for that. Delegates and Datasources are for different controllers/Objects to speak to one another when the alternative is to instantiate the controller/object from the navigationStack/view hierarchy. A Delegate forms a specific communication between the two that allows for clear knowledge in what their relationship is while keeping them decoupled (assuming you try to keep it that way). I disagree with the article that says callbacks are "better". They are amazing and I advise using them often, but just understand that most options that swift provides you with have a place where they work best.
I might be slightly bias, but Swift is an amazing language with OOP being a backbone and everything it has was well put together in order to provide the correct tools for each situation you find yourself in.
I often find myself using both of those tools and one other more customizable option in my more advanced setups where I have an overseeing viewController that manages many child controllers. It has direct access to all of them that are active but if any of its children communicate with it, it is through delegates. Its main job is just to handle their place on the screen though, so I keep everything manageable.
Delegates and data sources are more appropriate for offloading behaviors to other entities, not simple values. In other words, if your type just needs a value for something, you are correct that it makes more sense to expose that as a property that can be set from the client code.
But what should happen (for example) when a user taps a specific table view cell is a behavior that shouldn't be hard coded into UITableView. Instead, for flexibility, any implementation of that behavior can be created in a delegate and called by the UITableView when appropriate.
In general, think of delegation as a way to make subclassing unnecessary, because the methods you would normally override in a subclass are instead moved into a protocol that can be implemented by ANY type, not just a subclass of the base type. And instead of calling internally implemented methods to get certain behaviors, your type is simply calling those behaviors on an external collaborating class (the delegate).
So perhaps the best guideline for when to use a data source or delegate is the question: "Would I need to subclass this class in order to change this value or behavior in the future". If the answer is no, because you can just set a property from client code, then don't use delegation. If the answer is yes, then offload that behavior to a delegate or data source instead of forcing future programmers to subclass your class to make it work for their use case.
Delegate is an interface for the undefined activities.
so when you make a SDK or framework, you must provide an interface so that users can write a proper code for the interfaces' expecting activity.
i.e, Table View needs a datasource to show it's contents, but the apple's library developers doesn't know the content whatever contents their library users will use. so they provided an interface like datasource, delegate.
and in the library, they just call this methods. that's the way the library should be made.
But in your code, the label is defined very explicitly as well as it's in the current view, and you don't need to make an interface for an undefined activity.
if you want know more about this kind of coding style, you need to do some researches on Software Design Pattern.
https://en.wikipedia.org/wiki/Observer_pattern
https://en.wikipedia.org/wiki/Delegation_pattern
https://en.wikipedia.org/wiki/Software_design_pattern
I love apple's sdk very much, because they used all the needed design patterns very properly.
I have just starting developing application in ios and i have read so many tutorial for that but still i have not satisfy from that tutorial.
i want to know theoretical why we need to use category and what are the benefits.
Referenced from
http://www.g8production.com/post/37787310116/categories-in-objective-c-how-to-extend-methods
and
Difference between Category and Class Extension?
Categories and extensions allow you to extend the functionality of existing classes without subclassing (inherit nothing) adding functionality to an existing class, even to one for which you do not have the source.
A category allow you to add (only) methods to a class by declaring them in an interface file (.h) and defining them in an implementation file (.m), like in a basic Objective-C class. Sadly a category can’t declare additional instance variable for a class.
Now this declared methods become part of the categorized-class!!!
There’s no limit to the number of categories that you can add to a categorized-class, but each category name must be different should declare and define a different set of methods.
Edit
Categories
-> In objective c, when you want to add some more functionality to a class without inheritance, you simply use category for it.
-> Category use to add new method not properties
.
Class Extension
-> In objective c, when you want to make behavior of some property private you use class extension.
->mainly for properties.
A category allows you to add methods to an existing class—even to one for which you do not have the source.
Categories are a powerful feature that allows you to extend the functionality of existing classes without subclassing
How to use category in obj video
Benefit of using categories.
if you use categories then no need to keep in mind which custom class you have created for that specific feature. simply by using categories you can add new capability to existing class & by creating object of same class u can access it.
In one of my apps I wanted to change the default font. So instead of constantly changing the font where ever there was text, I set up a category were it changed the default font to the one I wanted.
I'm trying to add a new file to my Xcode project using Xcode 6.1.1 and Xcode now has a "File type" option where you select between "Empty File, Category, Protocol, Extension"
Can someone explain the differences between these and what the default to select would be? My file is a subclass of NSObject.
Thanks
Category
Categories are used to help modularize and organize class definitions. They allow you to take a (complex) class definition and spread it over several organized classes. It is not the same as subclassing. Although categories do allow you to override methods, Objective-C has no way of determining which method definition should be used, so you should never use a category to override methods. Instead, create a subclass that overrides the method as per usual.
Categories can contain protected methods, which "allow arbitrary files to 'opt-in' to a portion of an API by simply importing the category." (Check out the articles linked below.)
Extension
Extensions provide similar functionality to categories, except that you must implement the extension's API in the main implementation file.
Extensions can also be used to create a formal private API. Ordinarily, if you wanted to create private methods, you would write them in the implementation block, but would exclude them from the interface block. However, if you have an extensive group of methods that you would like to remain private, this becomes cumbersome and difficult to read/maintain. Using extensions, you can define the private methods in both the interface and implementation blocks of the .m file. As long as you do not include it in the respective .h file, these methods will be treated as private methods.
Extensions can also be used to make previously declared properties that are read-only outside the class read-write within the class (using the "self." syntax).
Protocol
Protocols allow for abstracted horizontal relationships across various (sometimes unrelated) classes and class hierarchies. A protocol consists of an API that can be used by a variety of classes, regardless of whether or not they are related. This allows you to modify/add some class functionality through a potentially wide range of classes without having to subclass them and alter their own class hierarchies.
In order to use a protocol, a class only needs to:
1. Include the protocol's name inside angled brackets <> after the class/superclass name declaration
2. Implement the protocol's methods
Protocols can also be useful for type checking.
Empty File
An empty file is just that - an empty file. You give it a name, but it contains no class information whatsoever (no generated methods, blocks, comments, etc.).
Sources: RyPress article on Categories and Extensions and RyPress article on Protocols. Both articles have helpful examples of each tool.
I am learning objective-C and I know we can use extension to add some private members to an interface.
But the book said there should be nothing in the ()
I read the following code snippet
#interface Tree(Private)
- (void)blah:(int)num;
#end
I am wondering why there is Private inside ()
You can put any name in the class category declaration, usually indicating the purpose of that category.
So in your case author of the code wanted to tell that those methods are for internal use of the class itself and are not intented to be called from other classes
The declaration in your example is precisely called a category (not an extension).
You can add as many categories as you like to any given Class (even if you don't have access to the source code). Categories allow you to add new methods to a class, but not new ivars nor properties. [1]
Each category has a name, which is the bit between parenthesis. There should not be two different categories for the same Class with the same name.
When the name is empty, this is called an extension. Extensions have some slight differences with categories: you can add ivars and properties to extensions and you can only use them for Classes for which you have access to the source code. [1]
Usually, extensions (like the example in your book) are declared at the top of the .m file, and are used for declaring methods, ivars and/or properties that are to be used only within that file (usually comprised of a single Class).
P.D.: If you really want to add new properties through categories as opposed to through extensions you can actually do so using associated objects [2][3].
http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html
Defining a property in iOS class extension
http://oleb.net/blog/2011/05/faking-ivars-in-objc-categories-with-associative-references/
In the case that is considered as a category, but since it's on the .m file, it will have the same effect. You can also see the tips from Xcode:
Being the mid one considered something like Tree(description) and the last one Tree ()
There are two closely related concepts here: class categories and class extensions. Class categories include a name inside the parenthesis and are most commonly used to add methods to existing classes or to organize methods into logical groups. Class extensions extend the internal implementation of the class (i.e. are used to define private properties, methods, etc).
More details can be found on Apple's dev site:
http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html
I use prism/mvvm/mef for my app, and loading all Views marked with ViewExport(Region) does work nicely (I'm using the StockTraderRI AutoPopulateExportedViewsBehaviour).
Now I'd like to use this runtime lookup capability to initialise some other background classes.
Say I got an interface
public interface ITable
{
}
And I got a lot of classes deriving from this interface.
Is there a way to mark those derived classes somehow and get MEF to create them on runtime and add them into some kind of list or container?
Like into a region which is not shown anywhere, I'd expect? How would I achieve this in MEF?
Sure there is!
Mark the classes inheriting your interface with Export attribute and in another class create yourself a property say of generic type ObservableCollection with attribute [ImportMany]. The should do the trick.
If you are using MEF instead Unity you can also use Container call within your bootstrapper :
var tables = Container.GetExportedValues<ITable>();
Container is the public property of your MEFBootstrapper.