#interface SomeClass
- (void)funcA;
+ (void)funcB;
#end
#interface Test
#property(nonatomic, assign) Class aClass;
#end
#implementation Test
- (void) test {
// that's ok
[[aClass new] funcA];
// but how to call class method?
[aClass funcB] ?
}
#end
XCode note "Instance method 'function' is being used on 'Class' which is not in the root class"
Have you tried ?
[[aClass class] performSelector:#selector(funcB)];
[((id)aClass) funcB];
or similarly to #Pancho's answer
[[aClass class] funcB];
Related
As topic as topic. That problem exists from class ObjectSubA, i can't call method of object ObjectX. At one condition methods must have same name of method.
file.h
#interface ObjectX : NSObject
- (void) insert;
#end
#interface ObjectSubA : ObjectX
- (void) insert;
#end
#interface ObjectSubB : ObjectX
#end
file.m
#implementation ObjectX
- (void) insert{
NSLog(#"answer");
}
#end
#implementation ObjectSubA
-(void)insert{
NSLog(#"nothing")
[self insert]; // <- need answer, should call insert from ObjectX
}
#end
#implementation ObjectSubB
#end
#implementation app
-(void)launch{
ObjectSubA * a = [[ObjectSubA alloc]init];
[a insert]; // ObjectSubA -> method insert -> ObjectX -> insert -> end. #ERROR
ObjectSubB * b = [[ObjectSubB alloc] init];
[b insert]; //ObjectX -> insert -> end. OK
}
#end
just call super
- (void)insert{
NSLog(#"nothing");
[super insert];
}
From the Objective-C documentation
Objects Can Call Methods Implemented by Their Superclasses
There’s another important keyword available to you in Objective-C, called super. Sending a message to super is a way to call through to a method implementation defined by a superclass further up the inheritance chain. The most common use of super is when overriding a method.
Considering the following case:
#interface Superclass : NSObject
...
#end
#interface Superclass
+ (void)methodToOverride
{
NSLog(#"This method should be overridden by subclass!");
}
+ (void)callMethodToOverride
{
[self methodToOverride];
}
#end
#interface SubClass : SuperClass
...
#end
#implementation SubClass
+ (void)methodToOverride
{
NSLog(#"I'm overriding this method!");
}
#end
Now, when calling
[Subclass callMethodToOverride];
I get "This method should be overridden by subclass!". Is it possible to get I'm overriding this method! instead or is this not possible with ObjC's static methods?
Cheers!
I use this paradigm from time to time and it works for me. In my implementations, I'm referencing [self class] instead of self. Maybe that's the key you're missing.
+ (void)callMethodToOverride
{
[[self class] methodToOverride];
NSLog(#"This is the class that I just used: %#", NSStringFromClass(self));
}
Sounds like it could just be a typo where you're not using the class you think you are.
I have a problem with an Objective-C class, when ARC is enabled.
My classes looks like these:
#interface ParentClass : NSObject {
}
-(void)decodeMethod;
#end
#implementation ParentClass
-(void)decodeMethod{
}
#end
#interface ChilldClass : ParentClass{
int *buffer;
}
#end
#implementation ChildClass
-(id)init{
self = [super init];
if(self != nil){
buffer = (int *)malloc(20*sizeof(int));
}
return self;
}
-(void)dealloc{
free(buffer);
}
#end
I have another class like this one:
#interface OtherClass : NSObject{
ParentClass *c;
}
#end
#implementation OtherClass
[...]
-(void)decode{
c = [[ChildClass alloc] init];
[c decodeMethod];
}
[...]
#end
As you can see, a ChildClass object is created and stored as an attribute in OtherClass. As long as the OtherClass object is living, the ChildClass object pointed by c should be also living, isn't it? Well, I have a BAD_ACCESS error, because after the ChildClass initialization, and before the decodeMethod is called, the dealloc method in ChildClass is automatically executed.
Why? ARC is enabled, so the dealloc method should be called automatically when the ChildClass object is released, but it shouldn't happen in this moment, because is still pointed with c.
Any help?
Thank you very much!
#interface ChilldClass : ParentClass{
It's possible your issue is caused by a spelling error in ChilldClass (typo?)
I'm working with a custom delegate and protocol functionality.
I implemented my class like follows:
#protocol MyDelegate <NSObject>
#required
- (void)update;
#end
#interface MyHandlerClass : NSObject
{
id <MyDelegate>delegate;
}
#property (nonatomic, weak) id <MyDelegate>delegate;
#end
My implementation class looks like:
#implementation MyHandlerClass
#synthesize delegate = _delegate;
- (void)updateRequired: (id)sender
{
if(delegate)
{
[delegate update];
}
}
#end
And from another class I'm setting it like:
[sharedManager setDelegate:self];
But when the updateRequired is triggered it is showing as nil.
Then I added a setter method like:
- (void)setDelegate:(id<MyDelegate>)aDelegate
{
delegate = aDelegate;
}
Everything works fine !!!
Then I changed the updateRequired method (without custom setter) like:
- (void)updateRequired: (id)sender
{
if(_delegate)
{
[_delegate update];
}
}
It is also working fine !!!
I couldn't find why it is not worked for the first case and why it is worked for the other two cases ?
Please help me to find the issue, Thanks in advance
When you use
if(delegate)
You are pointing to the instance variable "delegate".
However, when you use
[sharedManager setDelegate:self]
This is setting the instance variable "_delegate" to "self".
Try this:
if (self.delegate) {
[self.delegate update];
}
You have inadvertently declared one ivar called delegate
id <MyDelegate>delegate;
and another ivar called _delegate
#synthesize delegate = _delegate;
Some suggestions...
don't declare the iVar separately from your #property declaration
don't #synthesize, since XCode 4.4 you don't have to. The compiler will autosynthesize and autocreate an iVar with leading underscore
always refer to you ivar via it's property, inside and outside of your class. Only exceptions are in init, dealloc and inside custom setters and getters.
So this is how your code should look
#protocol MyDelegate <NSObject>
#required
- (void)update;
#end
#interface MyHandlerClass : NSObject
#property (nonatomic, weak) id <MyDelegate>delegate;
#end
#implementation MyHandlerClass
- (void)updateRequired: (id)sender
{
if(self.delegate)
{
[self.delegate update];
}
}
#end
To access your delegate property in the updateRequired method, you can do it by either using the private variable _delegate or by using self.delegate. Because when you synthesize using delegate = _delegate, setters and getters are automatically created.
This line tells the compiler to create a setter and getter for delegate, and that they should use the ivar called _delegate. Without the = _delegate part, the compiler would assume that the property and ivar have the same name.
I have a test case and a helper class. In the helper class I want to use asserts too like here:
MainTests.h
#import <SenTestingKit/SenTestingKit.h>
#interface MainTests : SenTestCase
#end
MainTests.m
#import "MainTests.h"
#import "HelperClass.h"
#implementation MainTests
- (void)testExample {
HelperClass *helperClass = [[HelperClass alloc] init];
[helperClass fail];
}
#end
HelperClass.h
#import <SenTestingKit/SenTestingKit.h>
#interface HelperClass : SenTestCase
- (void)fail;
#end
HelperClass.m
#import "HelperClass.h"
#implementation HelperClass
- (void)fail {
STFail(#"This should fail");
}
#end
Sidenote: I had to make the helper class a subclass from SenTestCase to being able to access the assertion macros.
The assertion from the helper class is ignored. Any ideas why? How can I use assertions in helper classes?
I had this same problem today and came up with a hack that worked for my purposes. Poking into the SenTestCase macros, I noticed that they call [self ...] on the helper but didn't trigger the asserts. So, wiring up the source class to the helper got it working for me. Changes to your question classes would look like:
MainTests.h
#import <SenTestingKit/SenTestingKit.h>
#interface MainTests : SenTestCase
#end
MainTests.m
#import "MainTests.h"
#import "HelperClass.h"
#implementation MainTests
- (void)testExample {
// Changed init call to pass self to helper
HelperClass *helperClass = [[HelperClass alloc] initFrom:self];
[helperClass fail];
}
#end
HelperClass.h
#import <SenTestingKit/SenTestingKit.h>
#interface HelperClass : SenTestCase
- (id)initFrom:(SenTestCase *)elsewhere;
- (void)fail;
#property (nonatomic, strong) SenTestCase* from;
#end
HelperClass.m
#import "HelperClass.h"
#implementation HelperClass
#synthesize from;
- (id)initFrom:(SenTestCase *)elsewhere
{
self = [super init];
if (self) {
self.from = elsewhere;
}
return self;
}
- (void)fail {
STFail(#"This should fail");
}
// Override failWithException: to use the source test and not self
- (void) failWithException:(NSException *) anException {
[self.from failWithException:anException];
}
#end
It is entirely possible that additional overrides are needed for more advanced functionality, but this did the trick for me.