I'm extending the NameAndPassword example (https://github.com/skycocker/NameAndPassword) and I need to acces IOBluetooth methods in this implementation file: https://github.com/skycocker/NameAndPassword/blob/master/NameAndPasswordPlugin.m
The interface looks like this:
#interface EXNameAndPassword : SFAuthorizationPluginView
How do I make it inherit from CBCentralManagerDelegate like in appdelegate:
#interface AppDelegate : NSObject <CBCentralManagerDelegate, CBPeripheralDelegate>
I need EXNameAndPassword to inherit both from SFAuthorizationPluginView and CBCentralManagerDelegate and stuff. I believe this is quite easy, I'm just an obj-c beginner. I read about composition but I can't get it to work.
What I have currently is
#interface EXNameAndPassword : SFAuthorizationPluginView <CBCentralManagerDelegate, CBPeripheralDelegate>
but I keep getting warnings about properties non synthesized -- I didn't have to synthesize them in my project which didn't require SFAuthorizationPluginView inheritance, therefore I guess I'm doing something wrong.
the "properties non synthesised" warning is related to properties defined in a protocol.
In a class #properties are automatically #synthesized in the implementation, but in a protocol, it is the conforming class's responsibility to synthesize, so add:
#synthesize protocolPropertyName = _protocolPropertyName;
in EXNameAndPassword.m
I got the problem.
#interface EXNameAndPassword : SFAuthorizationPluginView <CBCentralManagerDelegate, CBPeripheralDelegate>
is perfectly fine, I just had to disable architectures other than x86_64 in build settings.
Source: http://www.cocoabuilder.com/archive/cocoa/198573-property-problem.html
Related
This is from the ViewController.m file in a starter project from a tutorial for a game.
#interface ViewController()
//irrelevant stuff omitted
#end
It's the ViewController() bit that confuses me. I understand the different between public and private interfaces, but I haven't used a private interface til now in Objective-C. I'm used to seeing something like this instead, for the public interface:
#interface ViewController : UIViewController
So why now is it just the first one, and with parentheses, with no inheritance notation?
That's a class extension. It allows for declaring additional interface, usually private because it's in an implementation (.m) file. It's similar to a category, except that the compiler will require you to supply the implementation for any interface declared within it. (A category can declare an interface even if nothing provides any implementation.)
I am making a Cocoa application, and using Xcode for various code-generation. Works fine for generating .h and .m files for subclassing UIView, but when i subclass UIViewController i get an #interface declaration identical in both files, except that in the .m file it has ( ) at the end:
//in MyViewController.h
#interface MyViewController : NSViewController <MyViewDelegate>
#end
but also
//in MyViewController.m
#interface MyViewController ()
#end
#implementation MyViewController
#end
Yet it compiles fine. So, assuming this is normal behavior, the two-parts of question are:
(A) Why does this happen, and
(B) What are the results -- especially in terms of compile order?
Thanks!
when i subclass UIViewController i get an #interface declaration identical in both files, except that in the .m file it has ( )
As you noticed, the two interface blocks are not identical -- the () is important. The one with the () is a class extension, which is similar to a category without a name. The two important differences between a category and a class extension are:
You can declare instance variables in a class extension, but you can't in a category.
A class extension must appear in the same file as the implementation block.
Class extensions are useful for declaring instance variables and methods that you don't want to expose in the header file, such as methods or variables that are specific to the implementation and shouldn't be relied upon by users of the class.
Are you familiar with Categories? What you are observing is similar, but has important distinctions from Categories. The distinction here is that it is anonymous (hence the empty parens) and compiled at the same time the original class is compiled. That later part is an important part: it means you can add instance properties (storage). This is most commonly used to declare "internal only" or "private" methods and properties. But keep in mind that at runtime there is no notion of 'private' enforcement, it's all about what interface you have published vs. not published. This is just one way to have very clearly defined interface that is only 'published' to people who author the implementation file of the core class.
I'm still fairly new to Objective-C but I'd love to learn more about how it should be done.
I'm building a simple cheat sheet that I'd like to print and put on my office wall as a reminder.
Here's what I have so far:
// Headers (.h)
// Shows what's available to other classes
#interface ExampleViewController : UIViewController
// Declare public methods, ivars &
// properties that are synthesized.
#end
// Implementation (.m)
// Defines the content of the class
#interface ExampleViewController ()
// Class extension allowing to declare
// private methods, ivars & properties that are synthesized.
#end
#implementation ExampleViewController
// Private Properties
// Method definitions
#end
One thing I don't understand is why have both #interface and #implementation inside the implementation .m file?
I get that we can declare private stuff but why not simply throw them in #implementation like:
#implementation ExampleViewController
UIView *view; // private property
- (void)...more code
#end
#1 - Why should I ever use #interface from within my implementation .m file?
#2 - For header .h, why should I ever use #class more than #import?
#import actually gets the whole definition and #class tells the compiler that the symbol is a class. So I just don't see why I should ever use #class?
#3 - Otherwise, is there anything I should be adding somewhere in my .h or .m cheat sheet?
That's not a problem-related question but a more wiki-esque question so we everybody can look it up and completely and quickly understand those concepts as they are very hard to grasp for any newcomer.
Why should I ever use #interface from within my implementation .m file?
Because it's better to clearly separate public and private parts of the class.
For header .h, why should I ever use #class more than #import?
When forward-declaring classes for use in protocols. Like this:
#class Foo;
#protocol FooDelegate
// this wouldn't compile without a forward declaration of `Foo'
- (void)fooDidFinishAction:(Foo *)f;
#end
Otherwise, is there anything I should be adding somewhere in my .h or .m cheat sheet?
That's way too general to be answered in one post.
1 - Why should I ever use #interface from within my implementation .m file?
When you do not intend to expose that interface to any other component. That's certainly the case for private class extensions but may also apply for something like a test which doesn't need a .h file at all because while it does define a class it does not need to expose an interface for any other component to use.
2 - For header .h, why should I ever use #class more than #import?
Invert your question; why should I ever use #import rather than #class?
#class informs the compiler that a class definition of that name will exist to be linked but says nothing about it's interface.
#import makes the class' interface available to you.
A forward declaration requires less work and can allow for faster builds. It is also not always possible to #import a class at all times (as in circular references like #H2CO3's protocol example). If all you need to know is that a class exists then just use the forward declaration. When you actually need to interact with its specific interface (usually in your class' implementation) then you need to #import.
3 - Otherwise, is there anything I should be adding somewhere in my .h or .m cheat sheet?
Unless you intend to actually expose ivars as a public interface (almost certainly not the case) leave them out of your .h and expose only properties instead.
Keep your public interface as simple as possible. Try not to reveal implementation details. However keep it informative enough that users of the class can verify its behavior using that public interface. (I find test driving the design of the class using only it's public interface a good tool for striking this balance.)
Imports and forward declarations expose dependencies. Keep them to the minimum you actually need so that you can understand what the class in question actually depends on.
Delegate protocols and block types are a common part of a class' interface but not part of the #interface. Include them in the .h if they are needed by other classes (e.g. to register callbacks).
I came from front-end development, so MVC and OOP still give me some head shakes. Just to explain to you I send like 500 dicionaries (with 100 parameters) to a nodejs server. The problem is that I has creating ivars for each parameter and each dicionary. Now I want to create some classes like a person class, in the same header file that I have my syncronization class for example. I can make something like this on the header:
#import <Foundation/Foundation.h>
#import "GCDAsyncSocket.h"
#class GCDAsyncSocket;
#interface socketDelegate : NSObject<NSStreamDelegate>
{
NSInputStream *inputStream;
NSOutputStream *outputStream;
NSMutableArray *messages;
GCDAsyncSocket *socket;
dispatch_queue_t connectionQueue_;
}
- (void) initNetworkCommunication;
- (void) sendMessage:(NSArray *)message:(int)numberOfContactsToSend;
#end
#interface personInfo: NSObject
#property (nonatomic,weak)NSString*firstName;
#property (nonatomic,weak)NSString*lastName;
#property (nonatomic,weak)NSDictionary*dicToSendWithConctactInfo;
#end
But in the implementation I don't know how to handle the multiple classes. Like I've a method inside the "socketDelegate" class that needs to use the person class, but it's not available inside it.
What's the best way to implement this?
To answer your immediate question, you can just forward-declare personInfo at the top of the file before socketDelegate:
#class personInfo;
Usually you just put each public class in its own implementation and header files, and each implementation file includes the header files of all the classes it uses. The header files usually just need to forward declare the classes they refer to (as you are doing with #class GCDAsyncSocket;. However, it doesn't make sense that you are both importing #import "GCDAsyncSocket.h" and forward-declaring. From what you are using it for here, you don't need the import. However, to properly use GCDAsyncSocket, you will need to implement GCDAsyncSocketDelegate protocol, which will require you to import the header; however, you should probably implement that protocol as part of a "class extension" inside the implementation file).
You only need to import the header of something in your header if you are subclassing a class, or implementing a protocol that is declared in the header. For all other uses (i.e. using the class or protocol as part of a pointer type), you can simply forward-declare it. (And for implementing a protocol, you can do that in the implementation file with a "class extension" if you don't need people to know you're implementing the protocol.
Different classes should, typically, be in different files. Once PersonInfo (please capitalize class names) has it's own PersonInfo.h and PersonInfo.m, then you simply add
#import "PersonInfo.h"
to the header file above to be able to reference PersonInfo from your SocketDelegate class (again, please capitalize class names).
I'm trying to understand the Informal protocols, until now I know that Informal protocols are a kind of Category, but, why delegators don't have a category name?
Example:
#import <Cocoa/Cocoa.h>
#class FileSystemNode;
#interface AppController : NSObject { // Where is the Category ????
#private
IBOutlet NSBrowser *_browser;
FileSystemNode *_rootNode;
}
#end
Thanks.
Informal protocols are not "a kind of category".
If a class conforms to a protocol (for example #interface MyClass <MyProtocol>) it is guaranteed that you can call all methods on that class that are required by MyProtocol. (Unless the class doesn't really implement them [the linker can't know that because of dynamic binding], which is a programming error and a lie, but that is usually not the case.)
Categories on the other hand allow you to take an already existing class and extend it with new methods (for example adding a removeAllSubviews method to the already existing NSView class).
So, categories and protocols are quite the opposite of each other.