How to declare methods in objective c outside the interface? - xcode

When a method is declared in .h file is detected by intelisense and the warnings are not raised, when the method is used in .m file.
When a method is declared only in .m file, the intelisense doesn't detect it if is declared below the method where is being used.
To avoid the warnings there is a flag in xcode, but I prefer don't disable it.
There is any way to declare the methods in .m in order to be detected by intelisense and without the warning?
Thanks.

Two ways to fix it:
Either: Use a class extension to declare private methods at the top of the .m file:
#interface Foo ()
- (void)privateMethod;
#end
Or: Upgrade to Xcode 4.3.1, which contains a more recent version of clang. This newer version of the compiler does not need previously declared methods to call them in the same compilation unit.
Class extensions are still good for compatibility or to declare private properties, though.

You can use a category to declare additional methods on a class.
For instance, adding this at the top of your .m file:
#interface MyClass (PrivateCategory)
-(void)foo;
-(void)bar;
#end
will let Xcode know that MyClass additionally responds to foo and bar. The (PrivateCategory) tells the compiler that you're adding methods that should be "grouped" under the category PrivateCategory. You can pick whatever name you want, or even no name at all (although an "anonymous category" has slightly different semantics).

Related

Sharpie binding objective-c #protocols issue

I'm using sharpie bind command to get API interfaces for my iOS library for xamarin
sharpie bind --namespace=XXX --sdk=iphoneos9.2 Headers/*.h
Have issues with #protocol bindings:
The type or namespace name `IProfileDelegate' could not be found. Are you missing an assembly reference?
This is how it's generated:
interface XLibrary : IProfileDelegate
{
[Wrap ("WeakProfileDelegate")]
[NullAllowed]
MB_ProfileDelegate ProfileDelegate { get; set; }
I understand that it creates empty ProfileDelegate then compiler or something fills it with methods BUT my issue is that IProfileDelegate not found.
#protocol ProfileDelegate <NSObject>
#required
- (void)GetProfileFinished:(NSString*)_data;
- (void)SetProfileFinished:(NSString*)_data;
#end
Difference here in I symbol (which is reserved for #protocols I guess).
How to make sharpie generate proper api definitions?
I'm able to remove all I prefixes and it compiles successfully but I'd rather fix it not to repeat this every time I need to update source library.
Thanks
Remember that all the obj-c protocol act as a interface or abstract class i recommend to put "protocol, model and set base type as nsobject, another thing all the methods or properties maked as a "required" you need to specify it as Abstract
[Protocol, Model]
[BaseType (typeof(NSObject))]
interface myAwesomeDelegate
{
[Abstract]
[Export(...)]
void myRequiredMethod(uint param1)
[Export(...)]
void anotherMethod()
}
hope this will help you to fix your issue
According to the Objective Sharpie documentation:
In some cases these generated files might be all you need, however more often the developer will need to manually modify these generated files to fix any issues that could not be automatically handled by the tool (such as those flagged with a Verify attribute).
This means you will sometimes have to adjust the two generated files, ApiDefinitions.cs and StructsAndEnums.cs to fix issues, such as the one in this case.
You can read more about how bindings work for Objective-C protocols, which are similar to C# Interfaces, but not quite in the binding documentation.

Disabling *No visible #interface* error for unit test target

I have a category (on NSDate) that contains a method that is only called from another method within the category, so there is no need to expose the method in the category's header file.
However, as expected, if I call the method from a unit test, the compiler shouts that
No visible #interface for 'NSDate' declares the selector 'myMethod:'
I'd like to be able to turn off these particular errors (for the unit test target only, of course).
Can someone point me in the direction of the correct compiler flag?
Instead of turning them off why not just redeclare it? If you turn the warnings off completely then you lose the fact that the compiler will give you warnings in genuine places.
So just declare it above the unit test
#interface NSDate (UnitTests)
// your method sig
#end
#implementation YourUnitTest
//...

Best way of declaring private variables in cocoa

I would like to know what the recommendations are for declaring private instance variables in cocoa. This question is in the context of developing apps on the iPhone.
I am aware of at least three ways of declaring private variables:
Declare them in the interface of the h file with the modifier #private:
#interface MyClass : NSObject {
#private
NSObject * myPrivateVar;
}
Declare them in the implementation section of the m file:
#implementation MyClass
NSObject * myPrivateVar;
Declare a property in the interface of the m file (not even declaring the variable itself):
#interface MyClass ()
#property (nonatomic, retain) NSString* myPrivateVar;
#end
#implementation
#synthesize myPrivateVar;
So far, I have used extensively 2 but recently came to realize this might be dangerous due to the lack of garbage collection. Are there cases where it remains perfectly acceptable to use that method?
Is 3 more appropriate? Does the answer depend on the object type (e.g. mutable/immutable)?
Pointers to reference material discussing the trade offs for using/not using properties in general also appreciated.
Your three options have different semantics:
This creates an instance variable. Without garbage collection you need to retain/release objects you store into myPrivateVar.
This does not define an instance variable at all. Variables defined outside of the #interface and the scope of many method (or function) definitions are "global" - effectively class variables (which Objective-C has no special syntax for). Such a variable is shared by all instances of MyClass.
The difference between using a property (with or without the variable being explicitly declared) comes down to memory management. Defined as you have with retain means that there is no need for retain/release when you do not have garbage collection.
So don't use 2! Option 3 clearly has benefits if you don't have garbage collection, it provides some measure of abstraction over option 1, and is more costly - though you will probably not notice the difference outside of computationally intensive code which access the variable heavily.
Update 2015
Where garbage collection is used above ARC (automatic reference counting) is now more applicable (garbage collection is now deprecated). Also there is now a fourth option:
Declare them in the implementation section of the m file:
#implementation MyClass
{
NSObject * myPrivateVar;
}
Unlike option (2) this does declare an instance variable. The variable is private to the implementation, and with ARC memory management is automatic. The choice between this and (3) [which incidentally also no longer requires the #synthesize] comes down to choice and need; properties give you dot syntax, the ability to customise the setter and/or getter, and the copy attribute for automatic copy on assignment, but if you need none of these you can simply use the an instance variable.

Does Objective-C support Mixin like Ruby?

In Ruby, there's Modules and you can extend a class by "mixing-in" the module.
module MyModule
def printone
print "one"
end
end
class MyClass
include MyModule
end
theOne = MyClass.new
theOne.printone
>> one
In Objective-C, I find that I have a set of common methods that I want a number of Class to "inherit". What other ways can I achieve this without creating a common class and deriving all from that common class?
Shameless plug: ObjectiveMixin
It takes advantage of Objective-C runtime's capability of adding methods to a class in runtime (as opposed to categories, which are compile-time only). Check it out, it works pretty good and in a similar fashion to Ruby's mixins.
Edit: changes added because some people feel I am responsible for the limitations of Objective-C.
Short answer: you can't. Objective-C doesn't have the equivalent of Ruby mixins.
Slightly less short answer: Objective-C does have something with arguably the same flavour: protocols. Protocols (Interfaces in some other languages), are a way to define a set of methods an class that adopts that protocols is committing to implementing. A protocol doesn't provide an implementation though. That limitation prevents using protocols as an exact equivalent to Ruby mixins.
Even less short answer: However, the Objective-C runtime has an exposed API that lets you play with the dynamic features of the language. Then you step outside the language, but you can have protocols with default implementations (also called concrete protocols). Vladimir's answer shows one way to do that. At that point it seems to me you get Ruby mixins alright.
However, I am not sure I would recommend doing that. In most cases, other patterns fit the bill without playing games with the runtime. For example, you can have a sub-object that implement the mixed-in method (has-a instead of is-a). Playing with the runtime is OK, but has 2 drawbacks:
You make your code less readable as it requires readers to know a lot more than the language. Sure you can (and should) comment it, but remember that any necessary comment can be seen as an implementation defect.
You depend on that implementation of the language. Sure, Apple platforms are by far the most common ones for Objective-C but don't forget Cocotron or GnuStep (or Etoilé) which have different runtimes, which may or may not be compatible with Apple's on that respect.
As a side note, I state below that categories cannot add state (instance variables) to a class. By using the runtime API, you can lift that limitation too. This is beyond the scope of this answer however.
Long answer:
Two Objective-C features look like possible candidates: categories and protocols. Categories are not really the right choice here, if I understand the question properly. The right feature is a protocol.
Let me give an example. Suppose you want a bunch of your classes to have a specific ability called "sing". Then you define a protocol:
#protocol Singer
- (void) sing;
#end
Now you can declare that any of your own classes adopts the protocol the following way:
#interface Rectangle : Shape <Singer> {
<snip>
#end
#interface Car : Vehicle <Singer> {
<snip>
#end
By declaring that they adopt the protocol they commit themselves to implementing the sing method. For example:
#implementation Rectangle
- (void) sing {
[self flashInBrightColors];
}
#end
#implementation Car
- (void) sing {
[self honk];
}
#end
Then you use those classes for example like this:
void choral(NSArray *choir) // the choir holds any kind of singer
{
id<Singer> aSinger;
for (aSinger in choir) {
[aSinger sing];
}
}
Notice that the singers in the array don't need to have a common superclass. Notice also that a class can have only one superclass, but many adopted protocols. Notice finally that type checking is done by the compiler.
In effect, the protocol mechanism is multiple inheritance used for the mixin pattern. That multiple inheritance is severely limited because a protocol cannot add new instance variables to a class. A protocol only describes a public interface adopters must implement. Unlike Ruby modules it does not contain an implementation.
That's the most of it. Let's mention categories however.
A category is declared not in angle brackets, but between parenthesis. The difference is that a category can be defined for an existing class to expand it without subclassing it. You can even do so for a system class. As you can imagine, it's possible to use categories to implement something similar to mixin. And they were used that way for a long time usually as category to NSObject (the typical root of the inheritance hierarchy), to such an extent that they were called "informal" protocols.
It's informal because 1- no type checking is done by the compiler, and 2- implementing the protocol methods is optional.
There is no need today to use categories as protocols, especially because the formal protocols can now declare that some of their methods are optional with the keyword #optional or required (the default) with #required.
Categories are still useful to add some domain specific behavior to an existing class. NSString is a common target for that.
It's also interesting to point out that most (if not all) of NSObject facilities are in fact declared in a NSObject protocol. This means that it's not really compelling to use NSObject as a common superclass for all classes, though this is still commonly done for historical reasons, and well... because there is no drawback for doing so. But some system classes, such as NSProxy, are not NSObject.
You can literally mixin the code using #include. This is not advisable and is against all the religions in objective-c, however works perfectly.
Please, don't do it in the production code.
for example in the file:
MixinModule.header (should not be compiled or copied to the target)
-(void)hello;
MixinModule.body (should not be compiled or copied to the target)
-(void)hello{
NSLog(#"Hello");
}
in mixin class:
#interface MixinTest : NSObject
#include "MixinModule.header"
#end
#implementation MixinTest
#include "MixinModule.body"
#end
usage case:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]){
#autoreleasepool {
[[[MixinTest new] autorelease] hello];
}
return 0;
}
Please, don't do it in the production code.
This is my take on implementing Mixins in Objective-C, without using the Objective-C runtime directly. Maybe it's helpful to someone: https://stackoverflow.com/a/19661059/171933

Why would I make an all-optional message protocol?

I'm writing a Cocoa API for a project and the API takes a delegate. The protocol that I came up with declares all the methods as optional, but why would I do that instead of just documenting the delegate methods in a header file and taking a plain id as a parameter?
For the benefit of your users. If the object takes delegates conforming to some protocol and they pass something else in, the compiler can tell them. That isn't possible if you take an id and use a category as the delegate method interface.
Because having "all of these methods" optional isn't quite the same as permitting "anything you care to send".
It also produces code that is more usable in the IDE. For example if I'm looking at
#interface MyController : NSObject <FooBarDelegate> {
}
#end
I can command+double click in Xcode to jump to the definition of FooBarDelegate. With a category there's no formal declaration of intent to be a delegate.
Also, #required can be a problem for future plans with regard to backward binary compatibility and a new preferred method signature.

Resources