add Objective C instance Variables in category - objective-c

I know in objective c you can not add instance variable in category of interface. that is ok but today i see something i can not figure it out ,(why is this behavior right?)
#interface XXXX:NSObject
#end
#interface XXXX(){
#private
int x;
}
#end
why can i add add instance variable in empty () category , also why no one mention in in the internet.
Thanks All

You can add instance variables to anonymous categories/class extensions (Using just () for the category name), because they are essentially just a private extension of the main interface, and there can only be one.
However you cannot add new instance variables with named categories. You can make use of Associative References to work around this however.

Related

Adding methods to default Objects in obj c and swift

Hello I have been looking around for this answer and I've come across multiple articles but none of them have given me a straight answer. Lets say we have Object Date in objective C if I want to add methods to this object I would create a file similar to this:
obj c:
#interface Date (AdditionDate)
//methods
#end
in swift it seems to be a little different we do the following:
extension Date {
//methods
}
is this correct? Thank you for your help!!
Yep that's correct. What you are looking for is called a category in Objective-C terminology. It is the ability to add on methods to an existing class even if you don't have the original source code for that class. Keep in mind that you can't use categories to store any state on the original object, so instance variables are off the table.

How to access one private instance variable in ios

I have a question want to consult you。The following:
class A is from the ios framework, one instance variable B of the Class A is not public, can i through the getter methods defined in the category C to access instance variable B ?the category C is custom for the class A 。
example, the instance variable _viewDelegate of the class UIView.can I create a category C of the UIView to access instance variable _viewDelegate? if define method -(UIViewController*)viewDelegate in the category C;
ThankYou,First !
If the question is "can I access private variables via Category" then the answer is - depends.
First of all, the variable must be defined in the .h file.
If it is, then if marked as readonly, you can only read it. For example:
#property(nonatomic,readonly) somePropertyOfClassA
Otherwise, you can read/write to the property directly without a getter/setter, for example #property(nonatomic) NSInteger tag
The UIView _viewDelegate is marked as #package which means that the member is accessible only from the framework in which it is defined, which is the ios framework.

do category allow addition of instance variables in its implemenation?

I am working ios6.0 sdk with xcode 4.5.2
Here is following code i used to implement a category
.h
#interface NSObject (busyMode)
#property (nonatomic,assign) BOOL busy;
#end
.m
#implementation NSObject (busyMode)
BOOL _bsy;
-(BOOL)busy{
return _bsy;
}
-(void)setBusy:(BOOL)busy
{
_bsy = busy;
}
#end
as i read along many post, it says that we cannot have instance variables in category. And so above code should not work. But as i tried it out, all was working fine.
Has there been any changes related to category or was it just luck??
As others have pointed out, you didn't add an instance variable, but a global variable which is going to be shared among all of your instances.
Categories cannot add instance variables. However, you can simulate instance variables if you absolutely need them with objc_setAssociatedObject() and objc_getAssociatedObject().
That's because you have defined a single global variable, which isn't an instance variable.
Try and instantiate two instances of this object and you will observe that each instance cannot hold a different value.
You have not added an iVar. You have defined a global variable _bsy and are accessing it in the getter/setter for the property defined by your category.
I have a macro that lets you declare "properties" in categories like this:
#implementation NSObject (AwesomeUtils)
JESynthesize(assign, NSInteger, index, setIndex);
JESynthesize(strong, NSString *, name, setName);
JESynthesize(copy, void(^)(void), completion, setCompletion);
JESynthesize(unsafe_unretained, id, unsafeObject, setUnsafeObject);
JESynthesize(weak, id<UITableViewDelegate>, delegate, setDelegate);
JESynthesize(strong, NSString *, readonlyID, changeReadonlyID);
// …
#end
I say "properties" with quotes because you can use them even without the #property declaration. The macro also works around to support weak.
You can check the implementation here (the header files are at the bottom):
http://nspicks.com/2013/12/15/cleaner-properties-implementation-in-categories/

Get integer value from another class

I know i have done this before, but I just cant remember how to do it.
I have a integer, that i want to be able to change in another class of mine.
how do i do it?
MainViewClass : UIViewController {
int score;
}
#import "MainViewClass.h"
OtherClass : MainViewClass{
}
Then in the .m of OtherClass i want to be able to use the variable score.
How do i do this?
I have searched around the internet, and have tried several things to try to get it to work will no success.
Thanks for looking!
Have a wonderful day.
In your MainViewClass.h, you'll want to add your int as a property of that class.
#property (nonatomic, readwrite) int score;
Then in your MainViewClass.m, you'll want to synthesize the property using:
#synthesize score;
Now since your subclassing MainViewClass in your OtherClass you can access it's properties using some combination of the following.
In your OtherClass.h add
MainViewClass *mainViewClass;
in your OtherClass.m wherever you need access to the score, you should be able to access it as such.
mainViewClass = (MainViewClass *) self.parent;
and then the score using,
mainViewClass.score;
In your example, int score is an instance variable, or ivar for short. It's a piece of data associated with any given instance of MainViewClass. By default, and for good reason, instance variables have #protected visibility, meaning that only MainViewClass and its subclasses can access it.
Now, you made OtherClass a subclass of MainViewClass in your example, which means to access score from the same object you need only type score or self->score, and from another object that is a MainViewClass you need only type theOtherObject->score. (This sort of design exposes implementation details and so is often considered to be bad design by many coders, but for a simple use case like this you can probably get away with it. Why it's bad is a discussion that has raged for decades and is beyond the scope of this question.)
You create getter and setter methods (or a property with synthesized accessors) in the class with the integer, give the other class a reference to some instance of the first class, and have it use those accessors to get and set the integer.

Do Objective-C Category names do anything?

A class can be extended in Objective C using a category such as:
#interface NSString (CategoryName)
-(NSString *)myFabulousAddition; // a fabulous additional method
#end
/////////////////////////////
#implementation NSString (CategoryName)
-(NSString *)myFabulousAddition {
// do something fabulous...
}
#end
In this small example, I would be adding the method myFabulousAddition to NSString. I could then call it by [anNSString myFabulousAddition] just as if it were part of the NSString set of methods. Great and useful.
In the Apple documents regarding Categories, the docs state:
There’s no limit to the number of
categories that you can add to a
class, but each category name must be
different, and each should declare and
define a different set of methods.
What if you have something like this:
#interface NSString (CategoryName)
-(NSString *)myFabulousAddition; // a fabulous additional method
#end
#interface NSString (ANOTHERCategoryName)
-(NSString *)myFabulousAddition; // a DIFFERENT fabulous additional method
// BUT with same name as the other category
#end
/////////////////////////////
#implementation NSString (CategoryName)
-(NSString *)myFabulousAddition {
// do something fabulous...
}
#end
#implementation NSString (ANOTHERCategoryName)
-(NSString *)myFabulousAddition {
// do something equally fabulous, but DIFFERENT...
}
#end
The lack of a name in the parenthesis indicates that the form is an extension to the class, like so:
#interface MyObject () // No name -- an extension vs category to MyObject
- (void)setNumber:(NSNumber *)newNumber;
#end
Does the category name have any meaning to the compiler or linker? Is the category name part of the method signature in anyway or is it part of a primitive namespace? If the category name is meaningless, how do you know if you are about to stomp on another method and get undefined behavior?
The way to avoid stomping on methods is to prefix your category method names, like this:
#interface NSString (MyCompanyCategoryName)
- (NSString *)MYCO_fabulousAddition;
#end
If you get a collision of method names from different categories, then which one 'wins' at run time is completely undefined.
The name of a category is almost entirely useless, with the exception being that the nameless category (i.e. ()) is reserved for class extensions. Methods from class extensions are supposed to be implemented in the class' main #implementation.
The category name doesn't mean anything special, it's just an identifier. Unless the linker (or runtime loader) decides to give you a warning, there is no way to tell that multiple categories are defining the same method.
The behavior is (largely) unpredictable - one of the categories will win out, but you can't tell which one. Also, I think it's well possible you will start out with one implementation and end up with another one (if the second category is loaded after the first).
It certainly acts as an identifier, from the programmer's point of view. In the compiler point of view category methods are simply added as an extension of the class ( from which it is extending), regardless of the name.
And yes you can add categories of the same class with the same identifiers, even with same functions. But you definitely can't override any function because categories are just part of the class once you define them ( Just like you can't override a function of a class from within that class ).
As they are being added at runtime, they don't raise any error and only at runtime compiler selects the function, which is totally unpredictable.
i believe that they don't have any meaning. You don't really use them in your code ... Since they are categories and ... the semantic of a category ... is just to categorize something, i think this is somewhat logical ...
I would say they just simply gather the methods ...
On the other hand your question is very valid ... You DON'T KNOW if you override a method. If you are in the same project then the compiler issues a warning (or an error ? i don't remember), however if you are overriding a method from a library, then .. you are out of luck ...