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.
Related
The problem is I don't see the benefit of using associated objects vs static objects defined in the category implementation file with getter/setter methods.
I was thinking about defining the getters and setters in the header file of the category. Like this:
#interface NSObject (test_static)
- (id)getStaticObject;
- (void)setStaticObject:(id)a_static;
#end
and then to declare a static variable in the implementation file and implement getter/setter methods, like this:
static id test;
#implementation NSObject (test_static)
- (id)getStaticObject
{
return test;
}
- (void)setStaticObject:(id)a_static
{
test = a_static;
}
Why I shouldn't use this approach and use associated objects instead ?
Well, I guess I didn't get how properties work and how they've solved the fragile base class problem. Maybe it's related...
There is a huge difference. Associated objects is a way to simulate properties in a category.
Using a single static variable means you have a single, shared value used across all instances.
The choice is which to use depends on your goal. If you want an instance specific result from your two category methods, do not use a static variable - use associated objects. If you want the same object back from the two category methods regardless of the object instance, then use the static variable (and probably change your category methods to class methods instead of instance methods).
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Difference between self.ivar and ivar?
In Objective-C, what's the difference between [self setVariable: newStuff] and variable = newStuff?
When you have a class with a variable
#property (nonatomic) NSInteger num;
and you want to change the variable, typically you can do
[self setNum: newNum]
but you can also do
num = newNum
I know if you declare the variable readOnly, you can't use the first method to change it, but what's the concept behind it? Is it just because the second method with the setter can be called outside of its own class? Like if the class's instance was called 'sample'.
[sample setNum: newNum]
but then if you are changing the variable inside the class, either way is fine?
In Objective-C, what's the difference between [self setVariable:
newStuff] and variable = newStuff?
To be absolutely pedantic, one of them assigns the variable property the value in newStuff, whereas the other one assigns the value of newStuff to the iVar variable, but what I think you had in mind was a comparison between [self setVariable:
newStuff] and self.variable = newStuff. In that case, nothing is different, the compiler will expand case 2 out to case 1.
I know if you declare the variable readOnly, you can't use the first
method to change it, but what's the concept behind it? Is it just
because the second method with the setter can be called outside of its
own class? Like if the class's instance was called 'sample'.
readonly variables are important in cases where certain properties are private to the implementation of a class, but should be visible to other classes.
For example, if I were writing a Stack, I might want to expose the count of the number of items on the stack, but it would be a very bad idea for other classes to be able to write to the count variable. If I weren't smart and were using something like a count variable, I would want to be able to adjust the count of the semaphore internally (meaning you need it to be internally readwrite), so I declare a visibly readonly property so other classes can get it, but declare it internally readwrite so I can modify it:
//.h
#interface CFExampleStack : NSObject
#property (nonatomic, assign, readonly) int count; //readonly
#end
//.m
#interface CFExampleStack ()
#property (nonatomic, assign) int count; //readwrite
#end
Is it just because the second method with the setter can be called outside of its own class?
Well, that depends on how your instance variable is declared. By default, instance variables are #protected, i. e. they can be accessed from within the class and its subclasses only. However, if you explicitly declare an ivar as #public, then you can access it outside the class, using the C struct pointer member operator ->:
obj->publicIvar = 42;
However, this is not recommended, since it violates encapsulation.
Furthermore, if you use a custom setter method, then you have the opportunity to do custom actions when a property of an instance is updated. For example, if one changes the backgroundColor property of a UIView, it needs to redraw itself in addition to assigning the new UIColor object to its appropriate ivar, and for that, a custom setter implementation with side effects is needed.
Additionally, there are retained ("strong") and copied properties in case of instance variables that hold object. While writing a setter for a primitive type such as an integer is as simple as
- (void)setFoo:(int)newFoo
{
_foo = newFoo;
}
then, in contrast, a retained or copied property needs proper memory nanagement calls:
- (void)setBar:(Bar *)newBar
{
if (_bar != newBar) {
[_bar release];
_bar = [newBar retain]; // or copy
}
}
Without such an implementation, no reference counting would take place, so the assigned object could either be prematurely deallocated or leaked.
One more important difference...
Whenever you use self.prop KVC comes into play and you can observe the changes in the object, while _prop bypasses it.
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.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Prefixing property names with an underscore in Objective C
When synthesizing properties I found out that someone is doing:
#synthesize myVar = _myVar;
what is "_myVar" and which is the difference with simply doing :
#synthesize myVar;
Lastly when I should prefer the first solution to the last one?
Thanks
Luca
What _myVar really is in your example, is the name of the ivar that is backing your property. By default, when you synthesize a property, an ivar of the same name is created for you. So, you can use your property to set your ivar through setter/getter or the _myVar to directly access your variable (bypassing KVC/KVO of course).
EDIT:
From Apple's Coding Guidelines for Cocoa
...In many cases, when you use a declared property you also synthesize
a corresponding instance variable.
Make sure the name of the instance variable concisely describes the
attribute stored. Usually, you should not access instance variables
directly, instead you should use accessor methods (you do access
instance variables directly in init and dealloc methods). To help to
signal this, prefix instance variable names with an underscore (_)...
If you want to use some existing data member in setter and getter then it can be specify like that.
e.g. #synthesize personName=pName;
by this we can use pName instead of personName as per our convenience.
It the name of the private variable.
Se my answer on an other post: answer
When a new object is created and initialized why do we use id? Can't we use (NSObject*)?
Not every object in Objective C is NSObject. There are other root classes (for example, NSProxy), that are not derived from NSObject.
id means absolutely any object. Everything is Objective C that can receive messages (including Class) can be passed as id without type warnings.
NSObject* is only useful on objects that are actually derived from NSObject. If you pass something that is not derived from it, type checker will complain.
Because NSObject is a distinct Objective C class. It's the base class for most everything (* but not everything, +1 to HamsterGene), but it's still a class.
And if you assigned a new object (of any type that descends from NSObject) to it, you'd lose the inheritence & properties of whatever subclassed type you had created were.
id is roughly equivalent to void * in it's behavior where you can assign any Objective C object to an id, like how you can assign any random chunk of memory (with no care for it's contents or type) to a void *.