Will usage of static variables expose them to a danger of being modifiable from anywhere ?(In context of Objective-C). If yes, can someone suggest best alternatives for using shared variables across all classes ?
Is using too many static variables in Objective-C a bad practice?
Yes. Of course, "too many" has not been quantified and is subjective. Really, global/static variables are very rarely a good thing -- very convenient to introduce and very difficult to debug and eliminate. Also rare is the case that they are good design. I've found life far easier without them.
Will usage of static variables expose them to a danger of being modifiable from anywhere? (In context of Objective-C).
It depends on where they are declared and how they are used. If you were to pass a reference to another part of the program, then they would be modifiable from 'anywhere'.
Examples:
If you place them so that only one file can "see" the variable (e.g. in a .m file following all includes), then only the succeeding implementation may use it (unless you pass a reference to the outside world).
If you declare the variable inside a function, then it is shared among each translation and copied for each translation in C/ObjC (but the rules are very different in C++/ObjC++).
If yes, can someone suggest best alternatives for using shared variables across all classes?
Just avoid using globals altogether. Create one or more type/object to hold this data, then pass an instance of it to your implementations.
Singletons are the middle ground, in that you have some type of global variable/object based abstraction. Singletons are still so much hassle -- they are categorized as global variables and banned in my codebase.
Static variables are local to the translation unit, so the variables are definitely not modifiable from anywhere. Globals, which are closely related to statics in that they are allocated in the same memory area, are modifiable from anywhere, and that's their main danger.
When you need a group of variables to be accessible from anywhere in your project, the common approach is implementing a singleton that holds related data, and contains methods for processing that data. In MVC apps implemented in Objective C the model is often accessed through a singleton model object.
My scenario involves a number of static variables declared in the .h file & they are assigned values in specific methods declared in those .h files.
If you declare statics in the header, they become "disconnected" from each other: each translation unit (i.e. each .m file) gets its own set of statics from the header. This is usually not what you want.
If you make these variables global, you end up with a plain C, not an Objective C, solution. You should put these variables in a class as properties, and move function implementations with them into the methods of your class. Then make the class a singleton as described in the answer linked above to get a solution that is easier to understand than the corresponding solution based on globals.
Related
I'm making a method inside a Ruby on Rails app called "print" that can take any string and converts it into a png. I've been told it's not good to make class methods for base ruby classes like String or Array or Hash, etc. so "some string to print".print is probably not something I should do.
I was thinking about making a subclass of String called Print (class Print < String) and storing it in my lib/assets folder. So it would look like: Print.new("some string to print"). So my question is, am I on the right track by 1) creating a sub-class from String and 2) storing it in lib/assets?
Any guidance would be greatly appreciated!
Answers to your question will necessarily be subjective because there are always be many answers to "where should I put functionality?", according to preference, principle, habit, customs, etc. I'll list a few and describe them, maybe add some of my personal opinions, but you'll ultimately have to choose and accept the consequences.
Note: I'll commonly refer to the common degenerate case of "losing namespacing scope" or "as bad as having global methods".
Monkeypatch/Extend String
Convenient and very "OO-message-passing" style at the cost of globally affecting all String in your application. That cost can be large because doing so breaks an implicit boundary between Ruby core and your application and it also scatters a component of "your application" in an external place. The functionality will have global scope and at worst will unintentionally interact with other things it shouldn't.
Worthy mention: Ruby has a Refinements feature that allows you to do do "scoped monkeypatching".
Worthy mention 2: Ruby also lets you includes modules into existing classes, like String.class_eval { include MyCustomization } which is slightly better because it's easier to tell a customization has been made and where it was introduced: "foo".method(:custom_method).owner will reveal it. Normal Monkeypatching will make it as if the method was defined on String itself.
Utils Module
Commonly done in all programming languages, a Util module is simply a single namespace where class methods/static methods are dumped. This is always an option to avoid the global pollution, but if Util ends up getting used everywhere anyways and it gets filled to the brim with unrelated methods, then the value of namespacing is lost. Having a method in a Util module tends to signify not enough thought was put into organizing code, since without maintenance, at it's worst, it's not much better than having global methods.
Private Method
Suppose you only need it in one class -- then it's easy to just put it into one private method. What if you need it in many classes? Should you make it a private method in a base class? If the functionality is inherent to the class, something associated with the class's identity, then Yes. Used correctly, the fact that this message exists is made invisible to components outside of that class.
However, this has the same downfall as the Rails Helper module when used incorrectly. If the next added feature requires that functionality, you'll be tempted to add the new feature to the class in order to have access to it. In this way the class's scope grows over time, eventually becoming near-global in your application.
Helper Module
Many Rails devs would suggest to put almost all of these utility methods inside rails Helper modules. Helper modules are kind of in between Utils Module and Private Method options. Helpers are included and have access to private members like Private Methods, and they suggest independence like Utils Modules (but do not guarantee it). Because of these properties, they tend to end up appearing everywhere, losing namespacing, and they end up accessing each other's private members, losing independence. This means it's more powerful, but can easily become much worse than either free-standing class/static methods or private methods.
Create a Class
If all the cases above degenerate into a "global scope", what if we forcibly create a new, smaller scope by way of a new class? The new class's purpose will be only to take data in and transform it on request on the way out. This is the common wisdom of "creating many, small classes", as small classes will have smaller scopes and will be easier to handle.
Unfortunately, taking this strategy too far will result in having too many tiny components, each of which do almost nothing useful by themselves. You avoid the ball of mud, but you end up with a chunky soup where every tiny thing is connected to every other tiny thing. It's just as complicated as having global methods all interconnected with each other, and you're not much better off.
Meta-Option: Refactor
Given the options above all have the same degenerate case, you may think there's no hope and everything will always eventually become horribly global -- Not True! It's important to understand they all degenerate in different ways.
Perhaps functionality 1, 2, 3, 4... 20 as Util methods are a complete mess, but they work cohesively as functionality A.1 ~ A.20 within the single class A. Perhaps class B is a complete mess and works better broken apart into one Util method and two private methods in class C.
Your lofty goal as an engineer will be to organize your application in a configuration that avoids all these degenerate cases for every bit of functionality in the system, making the system as a whole only as complex as necessary.
My advice
I don't have full context of your domain, and you probably won't be able to communicate that easily in a SO question anyways, so I can't be certain what'll work best for you.
However, I'll point out that it's generally easier to combine things than it is to break them apart. I generally advise starting with class/static methods. Put it in Util and move it to a better namespace later (Printer?). Perhaps in the future you'll discover many of these individual methods frequently operate on the same inputs, passing the same data back and forth between them -- this may be a good candidate for a class. This is often easier than starting off with a class or inheriting other class and trying to break functionality apart, later.
I have been declaring variables both inside and outside a Class as shown below. My understanding of OOP is to limit their scope. However, to use them in other classes/files I put them outside (e.g."testLabel"). Mainly because it "works" and I am not familiar enough with OOP to do otherwise.
var testlabel:UILabel!
public var earth = SKShapeNode(circleOfRadius: 15)
class GameScene: SKScene , SKPhysicsContactDelegate {
var startTime = NSTimeInterval()
var skView:SKView!
My question is: What is best practice in Swift/OOP to make variables available to all classes?
I have read several discussions but still not clear on the dangers (versus convenience) of declaring variables publicly or globally.
Thanks for your help.
If you declare a variable outside of a class it becomes Global variable.
It's best practice to declare variables with in class if you don't use them in another classes.
I am not sure if there are any dangers if we declare as global variables.
The "dangers" of declaring global variables are more like "code smells" or bad practice. They aren't dangerous in that they will cause your code to crash, but they are dangerous in that they cause your code to become more unwieldy and more difficult to maintain, as your classes are not neatly encapsulated, and some of their functionality lives other places.
Sometimes global behavior is necessary, though. In that case, I think you should make a shared instance or singleton of some class that all other classes can reference. Then, instead of having magic floating variables, you at least encapsulate that behavior in one class that is easy to find and control. Apple uses shared instances all over their code.
http://www.raywenderlich.com/86477/introducing-ios-design-patterns-in-swift-part-1
https://thatthinginswift.com/singletons/
Why is it allowed to declare properties in categories when neither they nor their accessor methods are synthesized? Is there any performance overhead involved?
Is categorisation purely a compiler technique?
I'm trying to understand how categories work. This just explains what to do and what not to do. Are there any sources which go into more detail?
EDIT : I know that I can use associated references. Thats not what I'm asking for. I want to know why are the properties not synthesised? Is there a performance issue or a security issue if the compiler synthesises them? If there is I want to know what and how?
Why is it allowed to declare properties in categories [...] ?
Properties have many aspects (during compile- and runtime).
They always declare one or two accessor methods on the class.
They can change the selector when the compiler transforms dot notation to messages.
In combination with the #synthesize directive (or by default) they can make the compiler synthesize accessor methods and optionally ivars.
They add introspection information to the class which is available during runtime.
Most of these aspects are still useful when declaring properties in categories (or protocols) and synthesizing is not available.
Is categorisation purely a compiler technique?
No. Categories, as properties, have both compile time as well as runtime aspects.
Categories, for example, can be loaded from dynamic libraries at a later time. So there might already be instances of a class that suddenly gets new methods added. That's one of the reasons categories cannot add ivars, because old objects would be missing these ivars and how should the runtime tell if an object has been created before or after the category has been added.
Before you go into categories, please reconsider the concept of properties in Obj-C: A property is something you can write and read to in an abstract sense, using accessors. Usually, there is an instance variable assigned to it, but there is no need to do so.
A property may also be useful e.g., to set a number of different instance variables in a consistent way, or to read from severals variables or do some calulation.
The crucial fact here: there is no need to have an instance variable assigned to a property.
A category serves as an extensiton of an object's behavior, i.e., to extend its set of methods, without changing the data. If you see a property in it abstract sense, then it add accessors, thus it matches the idea of a category.
But if you synthesize it, an instance variable would be generated what contradicts the idea of a category.
Thus, a property in a category makes only sense if you use it in the uncommon, abstract way, and #synthesize is to ease the common way.
You may want to read NSHipster about how to implement properties storage in categories.
Quoting from the article: "Why is this useful? It allows developers to add custom properties to existing classes in categories, which is an otherwise notable shortcoming for Objective-C."
#synthesize informs the compiler to go ahead and provide a default implementation for the setter and the getter.
Said default setters/getters rely on the existence of some kind of storage inside the object.
Categories do not offer any extra storage, so default setters/getters would have no place to store into, or read from.
An alternative is to use:
#dynamic
and then provide your own implementation and own storage for the said properties.
One way is to use associated objects.
Another would be to store into/read from some completely unrelated place, such as some accessible dictionary of NSUserDefaults or ...
In some cases, for read only properties, you can also reconstruct/compute their values at runtime without any need to store them.
In Apple's Programming with Objective-C the section on Encapsulating Data states that:
You Can Define Instance Variables without Properties
It’s best practice to use a property on an object any time you need to keep track of a value or another object.
In other words they are strongly recommending that you use private properties rather than instance variables for any private object state.
I am wondering why this might be the case? I understand that properties have features such as KVO, and attributes (strong, weak ...), but in many cases I do not need these features and an instance variable will work just fine.
Are there any good reasons why instance variables might not be considered best practice?
Even though right now your private variable might work as a plain variable, you may decide later that some of properties 'goodies' are useful:
observing
atomic accessors
custom accessors
logging on access
access from subclasses
If you only access your variables as properties, you don't add much overhead (except in tight cycles) and leave room for reaping any of those benefits described above.
Basically, properties are useful even if you don't ever plan on making them public.
Of course, there are places where using an instance variable is still 'more natural', for example if you reimplement Foundation classes in a class cluster (such as NSArray), it's expected that your implementation is private and performant, so I don't use properties then.
Also, I don't think you should read too much into the advice. To me it reads more like "If you've only learned 5 minutes ago about properties and instance variables, let's start with using properties first".
People who are new to the language can go quite far without knowing what the instance variables are.
In other words they are strongly recommending that you use private properties rather than instance variables for any private object state.
Where did you read that they are recommending private properties? I think they mean public variables/properties.
And of course using properties instead of public instance variables has a lots of advantages:
encapsulation and custom getters/setters
memory management
KVO
binary compatibility
and so on
But in my opinion using private properties in general has no advantages and it's much easier to use private instance variables. The only reason I can imagine is to make custom getters/setters for such variables in future, but I don't think that it's a "best practice".
The point is underlaying storage abstraction. So simple yet very powerful.
This question is specifically focused around static libraries / frameworks; in other words, code that other people will eventually touch.
I'm fairly well versed in properties, since I started iOS development when iOS 6 was released. I have used hidden properties declared in interface extensions to do all of my "private" property work, including using readonly on public facing properties I don't want others to modify and readwrite within interface extensions.
The important thing is that I do not want other people who are using these static libraries / frameworks to be accessing these properties if I don't allow it, nor writing these properties if I let them read it.
I've known for a while that they could theoretically create their own interface extension and make my readonly properties readwrite themselves, or guess the names of hidden properties.
If I want to prevent this, should I be using ivars with the #private tag with directly declared ivars? Are there potential downfalls to doing it this way? Does it actually get me an additional measure of security, or is it a red herring?
Under ARC the only mode supported by properties and not instance variables is copy - so if you need copy use a property.
If you declare your private instance variables in the #implementation section:
#implementation MyClass
{
// private instance vars
}
then it takes serious effort to access them from outside the class. As you say accessing a "private" property just takes guessing its name - or using the library calls which tell you.
Is it worth it for security? YMMV. But its a good coding practice regardless.
Addendum
As the comment trail shows there has been much discussion over my use of serious effort.
First let's be clear: Objective-C is in the C family of languages, they all allow the programmer to just about anything they choose while staying within the language[*] - these are not the languages of choice if you want strong typing, access restrictions, etc., etc. within your code.
Second, "effort" is not an absolute measure! So maybe I should have chosen the word "obvious" to qualify it rather than "serious". To access a private property just requires the use of a standard method call where the object has type id - there is little clue in the code that the method being called is hidden. To access a private variable requires either an API call (a runtime function or KVC call) or some pointer manipulation - the resultant code looks nothing like a standard variable assignment. So its more obvious.
That said, apart from uses requiring copy, under ARC there is no good reason to use a private property when a private instance variable will do. For a private variable fred compare:
self.fred = 42; // property access, may involve a call (if not optimised out)
_fred = 42; // common way to bypass the accessors and get at the underlying var
fred = 42; // direct access
Take your pick, there is no right answer, but there isn't a wrong one either - this is the realm of opinion (and that is of course an opinion ;-)). I would often pick the last one, private variable - clean & simple. However #RobNapier in his answer prefers the use of properties.
[*] Note: once you consider linking to external code, say written in assembler, all bets are of in any language. At that point you have to look at the "hardware" (real or virtual) and/or "OS" to provide protection.
You should use private ("hidden") properties here. There is no "security" risk. The "attacker" in this scenario is the caller. The caller has complete access to all memory in the process. She can access anything in your framework she wants and there is absolutely nothing you can do to stop that (nor should you). This is true in any language. You can bypass "private:" designations in C++ as well if you know what you're doing. It's all just memory at the end of the day.
It is not your job to protect yourself or your framework from the caller. You both have the same goal: correct program behavior. Your goal is to protect callers from themselves. Make it difficult for them to use your framework incorrectly and easy to use it correctly.
So, you should use the tool that leads to the most correct code. And that tool is properties, and avoiding directly ivar access except in init and dealloc.