Adding properties in Objective-C category - ios

Is it recommended to add properties in categories to an Objective-C class? Is there an official Apple link?

First of all I want to say that Peter Segerblom's answer is not correct. But maybe Daji-Djan's comment is misleading.
From the very beginning:
A declared-property is solely a declaration of two (one – for readonly properties) methods. Period.
This means that it is a declaration.
This means that it refers to methods.
Therefore you can add declared-properties in a category.
But if the property is explicitly or implicitly (Apple: automatically) synthesized, it will synthesize an ivar, if there is none. This is impossible, because it would change the memory footprint of instance objects and a point in time, instance objects are already allocated.
So you have to do one of the things below:
Already having an ivar. (What makes it a bit meaningless.)
No synthesization of the declared-property.
However, this can be useful for computed properties, for properties, whose values are stored in another object, for properties, whose values are stored as associated object, for …

You can do this with associated objects. Although this is not recommended. This link has everything you need to know.
http://nshipster.com/associated-objects/
Section out of the blog:
Associated objects should be seen as a method of last resort, rather than a solution in search of a problem (and really, categories themselves really shouldn't be at the top of the toolchain to begin with).

You can easily do that -- if apple does this, I don't know. They often expose properties in categories though..
anyway, if it makes sense for your design, go ahead! Remember though that while you can add properties, you can't add variables to existing classes.
so either have computed properties, that are a kind of 'convenience wrapper' around existing functionality OR add variables using associated storage

You can't add properties to categories. I think this has something to do with the way memory is handled. Adding instance variables to a already existing object would change the size of the object.

Related

Why do we needed category when we can use a subclass? and Why we needed blocks when we can use functions?

These two questions are quite common when we search it but yet I need to get a satisfying answer about both.When ever we search a difference between say subclass and a category we actually get definition of both not the difference.I went to an interview to a very good MNC working on iOS and I was encountered with these two questions and I gave almost all the answers I have read here but the interviewer was not satisfied.He stuck to his questions and was that-
Why do we needed category when we can use a subclass?
Why we needed blocks when we can use functions?
So please explain me what specific qualities blocks and category add in objective C that their counter part can't do.
First...
Just reading the documentation "Subclassing Notes" for NSString shows why creating categories is sometimes better than subclassing.
If you wanted to add a function -(void)reverseString (for instance) to NSString then subclassing it is going to be a massive pain in comparison to categories.
Second...
Blocks are useful for capturing scope and context. They can also be passed around. So you can pass a block into an asynchronous call which then may be passed elsewhere. TBH you don't care where the block is passed or where it is finally called from. The scope captured at the time of creating the block is captured too.
Yes, you can use methods too. But they both have different uses.
Your questions are a bit odd. It's like asking...
Why do hammers exist when we can just use wrenches?
You can't use subclassing when someone else is creating the objects. For instance, NSString is returned from hundreds of system APIs, and you can't change them to return MyImprovedString.
Functions split up the logic; blocks allow you to write it closer together. Like:
[thing doSomethingAndWhenFinishedDo: ^{ some_other_thing; }];
the same code written with functions would put the second part of the logic several lines away in the file. If you have a few nested scopes in your logic then blocks can really clean it up.
Why do we needed category when we can use a subclass?
Categories let you expand the API of existing classes without changing their type. Subclassing does the same thing but introduces a new type. Additionally subclassing lets you add state.
Why we needed blocks when we can use functions?
Block objects are a C-level syntactic and runtime feature. They are similar to standard C functions, but in addition to executable code they may also contain variable bindings to automatic (stack) or managed (heap) memory. A block can therefore maintain a set of state (data) that it can use to impact behavior when executed.
You can use blocks to compose function expressions that can be passed to API, optionally stored, and used by multiple threads. Blocks are particularly useful as a callback because the block carries both the code to be executed on callback and the data needed during that execution
Category : It is used if we want to add any method on a given class whose source is not known. This is basically used when we want to alter the behaviour of any Class.
For example : If we want to add a method on NSString to reverse a string we can go for categories.
Subclassing : If we want to modify state as well as behaviour of any class or override any methods to alter the behaviour of the parent class then we go for subclassing.
For example : We subclass UIView to alter its state and behaviour in our iOS code.
Reference :
When to use categories and when to use subclassing?
What is the difference between inheritance and Categories in Objective-C
We need new method but we don't need new class so we need category.
We need function but we don't need named function so we need block.

Why isn't there a default implementation of NSCoding?

I understand how to use NSCoding to convert my objects to archive objects. That's not my question.
What I'm wondering is why there isn't a default implementation of NSCoding that could handle probably 99% of cases.
For instance, every time I write a custom class that I want to archive, I perform the following:
Implement -(void)encodeWithCoder: and -(id)initWithCoder:.
Go down my property list, writing a pair of statements (one encode, one decode) for each property.
If the property is an object, I use the encode/decodeObject method.
If the property is a value, I use the corresponding encode/decode method.
I always use the property's name as my key.
I would suspect that almost every implementation of NSCoding is exactly like mine, with the only changes being the particular properties that need to be manipulated.
It seems to me that this would be a perfect place for a standard implementation, with the option to override if your particular case if funky.
Do I have a misunderstanding of what's going on? If not, could I add a category on NSObject to implement this common method on all objects in my projects?
I suspect that the answer to your question is simply that NSCoding was designed long before Objective-C properties existed. (NSCoding was part of the OpenStep spec in 1994, whereas properties arrived with Objective-C 2.0 in 2007.) Additionally, some classes have properties that are not appropriate to be serialized for later.
However, your proposed solution could be a great time-saver! At least one such solution already exists. Check out AutoCoding.

Weak/Strong Annotations for Non-Synthesized Properties in Objective-C

Since Objective-C 2.0 we have properties, a nice syntax for getting and setting values for instance variables. Since Clang 3.1 all properties which are not dynamic, not readonly with an explicit getter or don't have a custom getter and setter are automatically synthesized to ivars. And since ARC we have weak/strong annotations for properties which are used by ARC to define the memory management logic of automatically synthesized properties.
The properties still can be synthesized manually e.g. for a readonly property backed by an ivar and returning a default value, for instance.
Sometimes, properties are also useful if they are not synthesized at all. I have found a few use cases when I use this sort of behavior:
A custom getter and setter which use a custom ivar for storing the actual value and which perform some additional actions.
A dynamic property, e.g. in subclasses of NSManagedObject.
A readonly property which simply passes through a property of an object stored in another property (e.g. a private one).
The Question: Does it makes sense to annotate these non-synthesized properties with weak/strong according to their actual usage or not? What is the best practice?
(https://twitter.com/kubanekl/status/427142577310408704)
I would say the answer is yes, even if only for documentation sake.
Even if you do not use any of the compiler and framework related default implementations, and implement everything by yourself, someone attempting to use these properties will be in much better position of understanding the API if he is able to get a hint on how the memory management would behave. A person does not really have to know how a setter or a getter is implemented internally, but he would might have to know, for example, if after calling a setter, the value was copied or retained or just assigned, and implement his side of things accordingly.
Yes, it does.
The property definition is a contract specification. Just because the compiler isn't fulfilling the contract doesn't mean you shouldn't respect it when manually implementing the accessor methods.

Objective C - Add property in runtime

I'd like to add an ivar to an existing objective-c class in runtime, but documentation states that an ivar cannot be an existing class, so I think property could still solve my issue.
As stated here class_addProperty(...) returns true, but when I try to access the ivar by it's name (or the property name) it always returns nil. What could be the issue causing this to happen?
You won't be able to add an ivar to the class at runtime. You can think of the class, and its ivars, as something like a C struct. It's layout is defined at compile time.
You can add properties at runtime (since these are just methods), and you can implement their getters and setters, but you'll need to come up with a different way to store any data that they represent.
Are you looking for something similar with some other programming language?
it looks like adding properties in AS3, but objc think the best would you use to store NSDictionary objects by keys.

Why I should access the instance variable directly from within an initialization method?

The Apple Programming with Objective-C document states that:
You should always access the instance variables directly from within
an initialization method because at the time a property is set, the
rest of the object may not yet be completely initialized. Even if you
don’t provide custom accessor methods or know of any side effects from
within your own class, a future subclass may very well override the
behavior.
But I don't know what side effects will be in a setter method, please give me a example to explain why I have to access the instance variable directly from within an initialization method
The answer is simple - it is code smell. Dot notation like self.foobar = something in Objective-C is just a syntactic sugar for messaging.
Sending messages to self is normally fine. But there are two cases you need to avoid them:
1. When the object is being created, and
2. When the object is being destroyed.
At these two times, the object is in a strange in-between state. It lacks integrity. Calling methods during these times is a code smell because every method should maintain invariants as it operates on the object.
If a setter method is overridden by a subclass, you have no guarantee that your instance variable will contain the correct data. If you want to maintain data integrity within your objects during a crucial phase such as initialization, you should do as Apple recommends.
In addition to #JacobRelkin point, side effects can include Key-Value Observing. Other objects can observe changes even during -init* and -dealloc. I've had a KVO -dealloc bug in the past.
It truly is a best practice to setup and tear down the ivars directly.

Resources