type casting self - objective-c

What does the following casting of self do "ClassA*"? Does this type caste allow you to access ClassA?
ClassA.h:
#interface ClassA: NSObject {
NSUInteger _someNumber;
ClassB *_classB;
}
#property (nonatomic,retain) ClassB *classB;
#property (nonatomic,assign) NSUInteger someNumber;
ClassB Method:
-(void) classBMethod {
[(ClassA*)self setSomeNumber:5];
}

As others have mentioned, if you are dealing with a subclass you should be fine but by the looks of your code I am guessing you would probably be better off with a protocol implementation see http://developer.apple.com/library/ios/#referencelibrary/GettingStarted/Learning_Objective-C_A_Primer/_index.html for an overview.
If that isn't a good fit then you may want to look at calling respondsToSelector first to see if the call will work. http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html#//apple_ref/occ/intfm/NSObject/respondsToSelector:
But overall, you shouldn't be casting self to another class....

A cast tells the compiler that the variable represents a certain type, even though it is not declared as such. It will get rid of compiler warnings, but it does not affect the compiled output. In this case, it is declaring that the instance of ClassB is actually an instance of ClassA so that it can call setSomeNumber:, but this will only work if the object actually implements that method. If the object is not a member of ClassA or a subclass, and its class doesn't implement the method, your program will crash at runtime.

Is ClassB a subclass of ClassA? If it is, no cast should be necessary.
You can cast any pointer to any class you want to disable a warning that it may not respond to the selector, but if it doesn't respond to the selector at runtime, your app will crash when it tries to call that method and the class does not respond.

Related

#property vs just declaring getter and setter

Is there any difference in behaviour - either at compile time or at run time - between this code...
// MyClass.h
#interface MyClass : NSObject
#property (nonatomic) SomeType myProperty;
#end
// MyClass.m
#implementation MyClass
#end
... and this code?
// MyClass.h
#interface MyClass : NSObject
-(SomeType)myProperty;
-(void)setMyProperty:(SomeType)myProperty;
#end
// MyClass.m
#implementation MyClass {
SomeType _myProperty;
}
-(SomeType)myProperty {
return _myProperty;
}
-(void)setMyProperty:(SomeType)myProperty {
_myProperty = myProperty;
}
#end
Obviously, the former version is more succinct and readable, but is there any difference in behavior? Do the synthesized getter and setter do anything more sophisticated than my straightforward implementation here? Is the declaration of a property distinguishable by introspection functions from declaration of a getter and setter? Are there any other differences I haven't thought of?
Short answer: No difference. However, some property attributes (copy or atomic) may require different accessor methods.
Long answer: There is a group of introspection functions that allow you to access all #properties declared for given class or protocol:
class_getProperty
class_copyPropertyList
protocol_getProperty
protocol_copyPropertyList
property_getName
property_getAttributes
I don't think any of these functions is useful in production code, because this is basically an implementation detail of the class. Also, there may be a getter/setter exposed in the public interface and a private property hidden in class extension.
Oh, and there's one other difference: Xcode highlights properties and plain getters differently :)
One difference is memory management. You can configure your properties to for example copy the object being set or to use a weak variable. Your code seem to be assuming ARC is active, since you are not releasing the old object and retaining the new object.
Before ARC a typical setter would to something like
-(void)setMyProperty:(SomeType *)myProperty {
if (myProperty == _myProperty) return;
[_myProperty release];
_myProperty = myProperty;
[_myProperty retain];
}
When you say you use ARC, then there is only a small difference. But none that matters.
Your ivar is #protected.
A #property creates an ivar which is #private.
Generally speaking:
So when you subclass, it is possible for your subclass to directly access the ivar you created, but not the one the property created.
BUT since you put your ivar in the #implementation block, the ivar is never seen by the subclass.
Without ARC however and SomeType being not an Objective-C object, there is a big difference. Then your setter/getter wouldn't have retain/release messages included.

Objective-C: Compiler error when overriding a superclass getter and trying to access ivar

I'm working on building an iOS 6 app.
I have a class TDBeam which inherits from superclass TDWeapon.
The superclass TDWeapon declares a #property in the TDWeapon.h file:
#interface TDWeapon : UIView
#property (nonatomic) int damage;
#end
I do not explicitly #synthesize the property, as I'm letting Xcode automatically do so.
In the subclass TDBeam I override the getter in the TDBeam.m file:
#import "TDBeam.h"
#implementation TDBeam
- (int)damage {
return _damage;
}
#end
Xcode auto-completes the getter method name, as expected. But when I attempt to reference the _damage instance variable (inherited from the superclass), I get a compiler error:
Use of undeclared identifier '_damage'
What am I doing wrong here? I've tried explicitly adding #synthesize, and changing the name of the _damage ivar, but the compiler doesn't "see" it or any other ivars from the superclass. I thought ivars were visible and accessible from subclasses?
Synthesized ivars are not visible to subclasses, whether they are explicitly or automatically created: What is the visibility of #synthesized instance variables? Since they are effectively declared in the implementation file, their declaration isn't included in the "translation unit" that includes the subclass.
If you really want to access that ivar directly, you'll have to explicitly declare it (in its default "protected" form) somewhere that the subclass can see it, such as a class extension of the superclass in a private header.
There are a lot of posts on this topic on Stack Overflow, none of which offer simple concrete advice, but this topic sums it up most succinctly, and Josh's answer is the best in any.
What he kinda stops short of saying outright, is, if this is the kind of thing you want to do, don't use #property at all. Declare your regular protected variable in your base class as he says, and write you're own setters and getters if you need them. The ivar will be visible to any subclasses who can then write their own setters/getters.
At least that's where i've landed on the issue, although I'd a total newb to subclassing.
The idea of creating private headers to host your anonymous category and re-#sythesizing your ivars in your subclass just seems wrong on so many levels. I'm also sure I've probably missed some fundamental point somewhere.
Edit
Okay after some lost sleep, and inspired by Stanford's 2013 iTunes U course, here I believe is an example solution to this problem.
MYFoo.h
#import <Foundation/Foundation.h>
#interface MYFoo : NSObject
// Optional, depending on your class
#property (strong, nonatomic, readonly) NSString * myProperty;
- (NSString *)makeValueForNewMyProperty; //override this in your subclass
#end
MYFoo.m
#import "MYFoo.h"
#interface MYFoo ()
#property (strong, nonatomic, readwrite) NSString * myProperty;
#end
#implementation MYFoo
// Base class getter, generic
- (NSDateComponents *)myProperty {
if (!_myProperty) {
_myProperty = [self makeValueForNewMyProperty];
}
return _myProperty;
}
// Replace this method in your subclass with your logic on how to create a new myProperty
- (NSString *)makeValueForNewMyProperty {
// If this is an abstract base class, we'd return nil and/or throw an exception
NSString * newMyProperty = [[NSString alloc]init];
// Do stuff to make the property the way you need it...
return newMyProperty;
}
#end
Then you just replace makeValueForNewMyProperty in your subclass with whatever custom logic you need. Your property is 'protected' in the base class but you have control over how it is created, which is basically what you are trying to achieve in most cases.
If your makeValueForNewMyProperty method requires access to other ivars of the base class, they will, at the very least, have to be be public readonly properties (or just naked ivars).
Not exactly 'over-ridding a getter' but it achieves the same sort of thing, with a little thought. My apologies if, in trying to make the example generic, some elegance and clarity has been lost.

Why do I have to cast the delegate?

I have a class and this class has a delegate protocol. I create an object in the main class using this class and assigned the main class as the delegate. The main class has a property I would like to read inside the created class. Then I do this:
BOOL prop = [self.delegate myProperty];
Xcode complains that "delegate may not respond to myProperty"
If I am sending a message to self.delegate to read myProperty, and generally Xcode never complains when you send a message to an not casted object, why do I have to do that
BOOL prop = [(myMainClass *)self.delegate myProperty];
to make it work?
To be more clear, here is an example of a message sent to an object without having to cast:
[self.myArray enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop){
int Number = [[obj dictionaryOfNames] count];
}];
self.myArray is an array of objects from another class that are dictionaries and have this property dictionaryOfNames. Xcode never asked me to cast this:
int Number = [[(myOtherClass *)obj dictionaryOfNames] count];
as I had to above for myProperty.
Different classes can conform to a protocol. If you declare that you conform to a protocol you just say that you will implement the requiered methods but you can implement it in a UIView, UIViewController, MyOwnClass, MyOtherClass etc.
Thats why a property is normally declared like this
#property (nonatomic, weak) id <MyProtocol> delegate;
So you just say your delegate is an object which conform to the protocol.
You haven't shown enough code to give a completely definitive answer, but in general terms I would expect that the definition of your delegate is not just id, you've probably used NSObject* or something similar.
The compiler is doing "static" analysis of your source code and trying to determine whether or not the object specified by "self.delegate" might implement that method. If the data type is, say, NSObject*, then the compiler looks through that specific class definition to see if your method is present; if it isn't, then you'll get a warning.
If the data type of the message receiver is id, the compiler tends to give up and say "well, it could be anything so I'll assume this will work".
The result of the expression [obj dictionaryOfNames] is probably of type NSDictionary and the compiler can see that that particular class does respond to the count method.
Note, you can also get this problem if you have specified a class name for a property, but the compiler cannot see the entire class definition from this file. For example, if you have
myobject.h:
#class Something;
#interface MyObject
#property (retain) Something *delegate;
#end
myobject.m:
#import "myobject.h"
[self.delegate doItYouFool];
then the compiler can see that the result of the expression 'self.delegate' is of type Something* but it can not see the actual definition of that class and thus can't look through its supported messages. This usually results in a warning about 'forward definitions'. To fix it, you should import "something.h" into the .m file, so that the compiler has full knowledge about the classes it is working with. To just silence the warning, you cast to id
[(id)self.delegate doItYouFool];
You may, of course, also be getting warnings that 'doItYouFool' isn't a known method, again because you haven't included the header file that defines that message.

Exposing/Synthesizing iVar properties in Objective c

I have a class that essentially acts as a light weight wrapper class around another class. It holds that other class as an iVar. I want to be able to expose certain properties (quite a few actually) of the iVar, but to do so I have to write out each property accessor like so:
- (void) setProperty:(Class *)value{
_iVar.property = value;
}
- (Class *) property{
return _iVar.property;
}
Of course, I have to do this for every single property, which is a pain (there are about 30 of them). I would love to be able to synthesize this but I haven't been able to figure out how.
Is it possible to synthesize?
Also, I can't subclass....well, I might be able to but it's really not recommended. The iVar class is really quite heavy (it implements CoreText). I'd rather write out the methods by hand.
Ok, so here's the solution I found...ended up being pretty simple once you knew what to do. First overwrite '- (id) forwardingTargetForSelector:(SEL)aSelector' and return the iVar:
- (id) forwardingTargetForSelector:(SEL)aSelector{
return iVar;
}
When the runtime is looking for a method and cannot find one, it will call this method to see if there is another object to forward the message to. Note that this method normally returns nil and if you return nil here, your program will crash (which is the appropriate behavior).
The second part of the problem is to shush the compiler errors/warnings you'll get when you try to send a message that's not declared. This is easily done by declaring a category you don't implement.
#interface Class (iVarClassMethods)
#propoperty (strong) Class *property1;
......more properties
#end
As long as you don't put in an implementation anywhere, aka #implementation Class (category), the compiler won't complain (it'll assume that the implementation is somewhere....).
Now the only drawback I see is if you change any of the properties in the interface of the iVar Class, you need to make sure you update all other classes that use the method described above, otherwise you'll crash when another class tries to send what is now the wrong method (and the compiler won't warn you beforehand). However, this can be gotten around. You can declare protocols in a category. So instead you create a separate protocol for the iVar class and move the methods/properties you wish out of the iVar class into the protocol.
#protocol iVarClassProtocol
#propoperty (strong) Class *property1;
......more properties
#end
Add that protocol to the iVar subclass so it has those methods declared through the protocol now.
#interface iVarClass <iVarClassProtocol>
....other methods/properties you don't need forwarded
#end
Finally, simply add the protocol to the category. So instead of the aforementioned category with explicit declarations you'll have:
#interface Class (iVarClassMethods) <iVarClassProtocol>
#end
Now, if you need to change any of the to-be-fowarded properties/methods, you change them in the protocol. The compiler will then warn you when you try to send the wrong method to the forwarding class.
I think you can forward the messages to the ivar:
- (void) forwardInvocation: (NSInvocation*) invocation
{
[invocation invokeWithTarget:ivar];
}
- (NSMethodSignature*) methodSignatureForSelector: (SEL) selector
{
NSMethodSignature *our = [super methodSignatureForSelector:selector];
NSMethodSignature *ivars = [ivar methodSignatureForSelector:selector];
return our ? our : ivars;
}
Then you have to hide or fake the type of your object, for example by casting to id, otherwise the compiler will complain that your class does not implement those methods.
Of course it would be best if you could come up with some better design that would do without such tricks.

How to provide additional custom implementation of accessor methods when using #synthesize?

I want to fire some code when a property is accessed and changed. I use #property and #synthesize in my code for my ivars. The properties are retained, so I'd like to keep that memory management stuff automatically generated by #synthesize.
However, I assume that #synthesize tells the compiler to generate the accessor methods code right where #synthesize is, so most of the cases at the top of the code, right?
And when I have a property foo, I get -setFoo and -foo methods. Could I then just make a method like this, to execute some more custom code when a property is changed?
-(void)setFoo {
// custom stuff
}
Now that's a problem. How to execute the first one? I wouldn't love to have a different name here. Is there maybe a way to let the #synthesize directive create other names for getter and setter methods, which I then call easily? And I would still be able to use the dot syntax then to access them?
You can use #property and #synthesize just like you normally would, but provide a custom setter or getter (or both) and those will be used instead. Typically I will do something like this:
// Override the setter
- (void)setName:(NSString *)aName
{
if (name == aName)
return;
[name release];
name = [aName retain];
//custom code here
}
When I use the set property, it will invoke my custom method. However, the get will still be synthesized.
If you provide an implemnetation for the setters or getters it will use that instead of the generated implementation. Its not hard to implement the "retaining" aspect of the getters and setters that are generated for you by the compiler when u synthesize, so you can just write your own getters and setters i would say and go with that.
One wacky solution is to create an abstract super class that does gives you the normal property synthesis.
Then create a concrete subclass that you will actually use, and that simply implements and override method (same signature) and calls super to do the actual setting.
This allows you to do whatever you want to do before or after the call to super's implementation.
Example:
#interface ALTOClassA : NSObject
#property NSString *catName;
#end
Nothing else needed in the .m beyond the stubbed file for this test.
Create the subclass, nothing needed specially in the #interface
#import "ALTOClassA.h"
#interface ALTOClassAJunior : ALTOClassA
#end
In the #implementation we do our override.
#import "ALTOClassAJunior.h"
#implementation ALTOClassAJunior
- (void)setCatName:(NSString*)aCatName {
NSLog(#"%#",NSStringFromSelector(_cmd));
[super setCatName:aCatName];
NSLog(#"after super: self.catName %#", self.catName);
}
#end
In use:
ALTOClassAJunior *aCAJ = [ALTOClassAJunior new];
NSLog(#"aCAS.catName %#", aCAJ.catName);
NSLog(#"set it to George.");
[aCAJ setCatName:#"George"];
NSLog(#"aCAS.catName %#", aCAJ.catName);
This allows you to leverage the autogenerated code, and still do stuff you want to do with your class. Abstract Super Class is often a useful solution for many things.
Yes, in your #property declaration, you can specify the getter and setter methods.
#property (readwrite,getter=privateGetFoo,setter=privateSetFoo:) NSObject * foo;
In your foo and setFoo: methods, call [self privateGetFoo] or [self privateSetFoo:f] then your custom code.
The object can also set an observer on itself with addObserver:forKeyPath:options:context:.
That said, I don't think either of these are very clean ways to do things. Better to write your own getter/setter as others have suggested.