How to get around incorrect warning in Xcode? - objective-c

I'm receiving the following warning:
Instance method 'method name' not found (return type defaults to 'id')
when this code is invoked:
#protocol SomeProtocol <NSObject> {
#property (nonatomic, retain) SpecificClassName* someDelegate;
}
...
+ (void) aMethod : (id <SomeProtocol>) object {
[object.someDelegate doSomeThing]; // warning statement show up here
}
I feel like this is a short coming of the compiler at this point, but that just may be the pot calling the kettle black ... does anyone have any feedback on this?

You need to #import the header file for SpecificClassName, in your implementation (.m file).
If you're going to use the type name SpecificClassName in the header file, a forward declaration #class SpecificClassName will do, but calling a method on the class requires the compiler to know the return type of the method.
If you want to call a method on an instance of SpecificClassName, include the header in which it's defined.

I means that the header file for the class doesn't include the method signature. So the compiler can't tell if the method is actually there. Fix the header file to get rid of the warning.
In Java or C++, this would be a compilation failure. That's because they do method binding at compile-time, so the compiler needs to find the methods. Objective-C does it at run-time; it sends a method call to an object, and the object may or may not have such a method.

Related

Why cannot add method in category extension in objective-c?

With given class TestViewController, if a method is added to its extension. But error will pop up, what is the reason?
Code:
#interface TestViewController (){
-(void) testMethod;
}
Parse error: TestViewController.m:12:5: Type name requires a specifier or qualifier
How to add a method to extension class which extend a anonymous category? thanks
Remove the {}. ivars are declared inside {}, methods are declared outside the {}.

Calling objective-c method from Swift error

I get an error when I try to call objective-c method from swift.
my objective-c .h class:
#class myType;
#interface myClass : NSObject
- (myType *)myMethod;
then I will create an object form myClass and try to call myMethod in swift (I have declared anObject of type myClass):
let a = anObject.myMethod();
but I get an error:
Value of type 'myClass' has no member 'myMethod'
If I change myType to something else, the error goes away. So it should be a problem of not recognizing myType in swift..
I appreciate any help
#class myType;
is only a "forward declaration" of that class. In order to call the
- (myType *)myMethod;
method from either Objective-C or Swift, the compiler needs to know the
actual interface declaration of that class. So "myType.h" or whatever
file contains
#interface myType : NSObject
// ...
#end
must be included from the bridging header file.
Remark: Class names should start with a capital letter.
turned out the real problem for me was something else!
I had to simply delete the derived data:
Window -> Projects -> Derived Data -> Delete
Clean Project
Quit Xcode
Open Xcode
Build Project
Apparently, using swift I have to these steps more often..

What is the correct way of accessing a Swift Delegate from Objective-C?

Environment: Xcode 6.1.1 & Xcode 6.2 Beta
Greetings:
I need to publish a NSString within a Swift doc from a neighboring Objective-C doc within the same project. For example, display "Hello World" generated in Objective-C upon a Swift page. I've made a proof-of-concept demo; based on feedback.
I'm thinking of using an ObjC --> Swift delegate via a protocol pattern as shown below:
Note: the Swift file is the delegate.
Here I'm calling the delegate method in Swift, from Objective-C:
#pragma mark - Action methods
- (IBAction)sendDelegateAction:(UIButton *)sender {
[_delegate radiusString:#"Hello World"];
}
I've instantiated the Objective-C file to link the delegate to the instance (I hope I got it right):
let geo32Controller = MyObjCTableViewController()
geo32Controller.delegate = self
So far, the compiler complained that the Swift protocol couldn't be found.
Here's the protocol (declared in Swift):
#objc protocol DiscoveryContributeProtocol {
// optional
func radiusString(radiusString:String)
}
And here's the delegate reference to that protocol in the Objective-C header file:
#interface MyObjCTableViewController : UIViewController<UITableViewDelegate, UITableViewDataSource>
#property (nonatomic, weak) id<DiscoveryContributeProtocol> delegate;
#end
However, the compiler can't find the protocol:
BTW: when I put the bridge reference in the ObjC's header file, I get a compiler error:
Two Questions:
Do I have the correct pattern (did I instantiate the ObjC correctly) ?
How do I make the Objective-C portion see the Swift protocol for the delegate link?
You have the right idea, but have a few bugs that are preventing this from working.
You've declared Geo32Boundaries as conforming to the DiscoveryContributeProtocol, but it doesn't need to and doesn't actually implement it, it only has a property that conforms to that protocol. That's the source of the "Method 'radiusString:' not implemented" error:
#interface Geo32Boundaries: UIViewController // <-- that's all you need
You're setting the delegate incorrectly -- the code you have there looks like it's trying to set a class instance of Geo32Boundaries to self, but you're also trying to call it like a function. You'll need to set the delegate on a the instance of the Geo32Boundaries view controller that is being presented to the user. I don't know where that code lives, so I can't give a great example, but it'll be something like:
geo32Controller.delegate = self
Lastly, though not a bug, your protocol should really be called DiscoveryContributeDelegate -- we usually don't use "protocol" in the protocol name.

Objective C - Error with custom return type?

I'm very new to Objective-C, so this is probably very basic.
Anyhow, I am trying to specify a custom return type in my class, and I keep getting errors that the class either needs an asterisk* or is not considered a type at all. I read that you need to use #class instead of #import in your header files, but that doesn't seem to help in this case. What else am I doing wrong?
Here is my code:
#import <Foundation/Foundation.h>
#class Room;
#interface LevelData : NSObject {
#private
NSArray *data;
Room *currentRoom;
}
+(void)initialize;
+(*Room)getCurrentRoom;
#end
Thanks a bunch!
change that one line to:
+(Room *)getCurrentRoom;
and see if that compiles. Room * indicates you're returning a pointer to a Room Objective-C object.
The asterisk should go after the class name, like a standard C-style
pointer.
Class methods should return a value,
usually a pointer to an object of the same class, so if you do use
initialize you'll want it to return a Room*.
Good coding practice is to override -(Class *) init;, but
only if you need to. This is because the first thing you (or someone
else using your code) should/will do when using an object (usually)
is to call some form of [[Class alloc] init]. If they call this
when you have a special initialize function, it will call the
NSObject -(NSObject *)init; method instead, and your instance
variables won't get setup.

Is it possible to declare a method as private in Objective-C?

Is it possible to declare a method as private in Objective-C?
If you're working in Objective-C 2.0, the best way to create methods that are "hard" for others to call is to put them in a class extension. Assuming you have
#interface MyClass : NSObject {
}
- (id)aPublicMethod;
#end
in a MyClass.h file, you can add to your MyClass.m the following:
#interface MyClass () //note the empty category name
- (id)aPrivateMethod;
#end
#implementation MyClass
- (id)aPublicMethod {...}
- (id)aPrivateMethod {...} //extension method implemented in class implementation block
#end
The advanage of a class extension is that the "extension" methods are implemented in the original class body. Thus, you don't have to worry about which #implementation block a method implementation is in and the compiler will give a warning if the extension method is not implemented in the class' #implementation.
As others have pointed out, the Objective-C runtime will not enforce the privateness of your methods (and its not too hard to find out what those methods are using class dump, even without the source code), but the compiler will generate a warning if someone tries to call them. In general, the ObjC community takes a "I told you not to call this method [by putting it in a private class extension or category or just by documenting that the method is private] and you called it anyways. Whatever mess ensues is your fault. Don't be stupid." attitude to this issue.
No, any object can send any message to any other object. You can, however, put the method in a category that's part of the class's implementation file. That way, you'll get a "Class may not implement this method" warning if you try to call it anywhere else. That's the normal way of making a method "private."
There is nothing that will prevent the method being called (since objective-c is message based anything can be sent any message), but you can declare them outside of the header so they are not visible and the compiler will generate warnings if used.
This works for both class and instance methods.
E.g.
#import "SomeClass.h"
// Interface for hidden methods
#interface SomeClass (hidden)
+(void) hiddenClassMethod;
-(void) hiddenInstanceMethod;
#end
Note: Do NOT declare variables like this or they will become class-variables - e.g. only one variable will be used by all instances.
You can do so by using categories. I've got a fuller description in my answer to this SO question.
As has been said, you can't stop anyone sending a message to a selector, but by using categories you can reduce the visibility of these functions.
Also, you can have more than one category extending a class. So, by using informative category names you can group private functions into related blocks, improving the self-documenting nature of your code.
As others mentioned, you can't have code that's
a method, and
impossible to call from outside a class.
Folks have already pointed out that you can abandon point 2, and get a method that's hard-but-not-impossible to call. Alternatively, why not abandon point 1?
static id myPrivateMethod(MyObject *me, int arg1, id arg2) { ... }
Now the code can only be called from within same file. You don't get any of the magic private-member access you can get with a method, so this is by no means a perfect solution. But there's no better way to achieve privacy.
To implement hidden methods (instance and/or class)
// ===========================
// = File: SomeClass.m
// ===========================
#import "SomeClass.h"
// =================================
// = Interface for hidden methods
// =================================
#interface SomeClass (hidden)
-(void) hiddenInstanceMethod;
#end
// ================================
// = Implementation for SomeClass
// ================================
#implementation SomeClass
-(void) hiddenInstanceMethod
{
printf( "Hidden instance method\n" );
}
-(void) msg
{
printf("Inside msg()...\n");
[self hiddenInstanceMethod];//private method calling
}
#end
http://macdevelopertips.com/objective-c/private-methods.html
reffer this link it will be helpful .