I am trying to implement component for possibility to apply different skins to views and controllers at runtime without reinitialising these controls. I want to use such logic:
Declare protocol with methods for applying skins.
All necessary classes implements this protocol.
When user selects skin all instances of classes that conform to protocol receive message to apply skin.
So I know how to get all necessary classes that conform to my specific protocol by using objc_getClassList and class_conformsToProtocol functions.
But how to get all allocated instances of these classes for sending message to them?
I know that it could be implemented by internal logic of every class by storing all instances in static storage and returning array by class method. But it isn't elegant solution. I'm finding more universal solution where I can add new skinnable controls in easy way.
It sounds very much like you're reinventing <UIAppearance>. You should at least start there. It's what it's for. Also see Peter Steinberger's writeup for discussion of adding custom properties.
To your basic question, there is not a runtime call to enumerate all allocated objects of a class. It would add a lot of overhead to provide that (objects come and go all the time and very quickly). Even if you could do it, you probably shouldn't. But since you're talking about visible views, then you can always do this by enumerating the view hierarchy under NSWindow. Any views not currently in the view hierarchy should be expected to correctly redraw in an new style the next time they come on the screen.
But I'd start with <UIAppearance>.
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 a few ViewControllers in my storyboard. Lets call them:
SB_VC1
SB_VC2
SB_VC3
I have one ViewController.swift file. Within that file, I have multiple ViewController classes, let's call them:
VC_Class_1
VC_Class_2
VC_Class_3
Each VC_Class is used as its corresponding SB_VC's class. Each VC_Class has different code, tailored to what I want the SB_VC to do.
These are all on the same hierarchy level, none is a subview of another. They each inherit from UIViewController and import UIKit and CoreData.
Question:
Part 1
Is keeping the code for all three classes in one file wrong? Should I be creating a new file for each VC_Class? Or is this just a matter of personal preference? If it is not preference and is clearly wrong, what is the problem it causes?
Part 2
If all three do have a little bit of overlap, in terms of each having a few functions that are the same, should I create a fourth class and call it something like "ToolBox.swift" and use it to call those functions? Or would it be better to have VC_Class_1 house those functions and make VC_Class_2 and VC_Class_3 inherit from VC_Class_1?
Generally, it is a matter of preference. Though I'd highly advise against it. Large files are harder to maintain, and it will take you longer and longer to find pieces of code you need. It will also be easier for other people to read and undestand your code.
As for the common code, it depends on its nature. You can either create a Toolbox class or a superclass from which you will inherit.
Particularly in iOS and Cocos2d. What if i need a lot of classes to interact with say CCScene or UIView which is only one in my application? Is it normal to make it shared, an ordinary singleton? What are pros (if they are there) and cons of such an approach?
few cons:
you won't be able to create new instances of your element - for example if you want to create a new view or scene and replace the old one
you have to consider instantiation from different threads
if you change a method's signature, you'll have to update many classes
I think it's better to implement the MVC pattern if the element is view or a wrapper for other type of element and make all your classes use this controller/wrapper.
From a "good-design" perspective. Should I use the appDelegate class for all app-level common code? In other words, I have many things that many view controllers need to be able to do. That means it's common functionality, not specific to a single view controller. So the question is: Should I house these common methods in the appDelegate? Is that what it's for? Should I create another separate class?
Here are a few examples of the common functionality I speak of:
1) Play a common sound (such as error sound).
2) Show an alert message (such as an error message).
3) Method to validate input that should be of a specific type (decimal-numeric)
4) Update app-level data from a web service
Put all common functions to appDelegate class is not good idea.
1 & 2) You can create super class and all your view controller inherit it or use category.
3 & 4) You can create a normal function class to achieve. e.g. Your class name is Function and you have class method, to use it just simple call [Function validate:yourdata] return boolen value.
If it's data-related, then having a separate Model layer in your app makes the most sense to me. If it's code related specifically to how you like your view controllers to behave then a common super-class or even a UIViewController category sounds more like the right solution.
I see the app delegate as more about setting up the basic application structure (which might include connecting the Model and Controller layers) and dealing with its life cycle.
I'm currently working on a Rails project, and have found times where it's easiest to do
if object.class == Foo
...
else if object.class == Bar
...
else
...
I started doing this in views where I needed to display different objects in different ways, but have found myself using it in other places now, such as in functions that take objects as arguments. I'm not precisely sure why, but I feel like this is not good practice.
If it's not good practice, why so?
If it's totally fine, when are times that one might want to use this specifically?
Thanks!
Not sure why that works for you at all. When you need to test whether object is instance of class Foo you should use
object.is_a? Foo
But it's not a good practice in Ruby anyway. It'd much better to use polymorphism whenever it's possible. For example, if somewhere in the code you can have object of two different classes and you need to display them differently you can define display method in both classes. After that you can call object.display and object will be displayed using method defined in the corresponding class.
Advantage of that approach is that when you need to add support for the third class or a whole bunch of new classes all you'll need to do is define display method in every one of them. But nothing will change in places where you actually using this method.
It's better to express type specific behavior using subtyping.
Let the objects know how they are displays. Create a method Display() and pass all you need from outside as parameter. Let "Foo" know to display foo and "Bar" know how to display bar.
There are many articles on replacing conditionals with polymorphism.
It’s not a good idea for several reasons. One of them is duck typing – once you start explicitly checking for object class in the code, you can no longer simply pass an instance of a different class that conforms to a similar interface as the original object. This makes proxying, mocking and other common design tricks harder. (The point can be also generalized as breaking encapsulation. It can be argued that the object’s class is an implementation detail that you as a consumer should not be interested in. Broken encapsulation ≈ tight coupling ≈ pain.)
Another reason is extensibility. When you have a giant switch over the object type and want to add one more case, you have to alter the switch code. If this code is embedded in a library, for example, the library users can’t simply extend the library’s behaviour without altering the library code. Ideally all behaviour of an object should be a part of the object itself, so that you can add new behaviour just by adding more object types.
If you need to display different objects in a different way, can’t you simply make the drawing code a part of the object?