Complier Directives in Objective-C
@, or "at" sign compiler directives, are as central to understanding Objective-C's gestalt as its ancestry and underlying mechanisms. It's the sugary glue that allows Objective-C to be such a powerful, expressive language, and yet still compile all the way down to C.
Interface & Implementation
1. @class
2. @interface
3. @implementation
4. @end
Instance Variable Visibility
5. @public
6. @private
7. @protected //default
8. @package
Properties
09. @property
10. @synthesize
11. @dynamic
Protocols
12. @protocol
13. @required //default
14. @optional
Exception Handling
15. @try
16. @catch
17. @throw
18. @finally
Object Literals
19. @" string "
20. @42, @3.14, @YES, @'Z'
21. @[ ]
22. @{ }
Objective-C Literals
24. @selector ( )
25. @protocol ( )
C Literals
26. @encode ( )
27. @defs ( )
Optimizations
28. @autoreleasepool { }
29. @synchronized { }
Compatibility
30. @compatibility_alias
Now Details with Definition and Example
Interface & Implementation
1. @class : Used for class forward declarations.
Declares the names of classes defined elsewhere without having to import the class' header file.
Forward Class Declarations : Occasionally, @interface declarations will reference an external class in a property or as a parameter type. Rather than adding #import statements for each class, it's good practice to use forward class declarations in the header, and import them in the implementation.
Example. if I want to use MyClass data In my MyViewController class. So in MyViewController.h file I do like this
#import <UIKit/UIKit.h>
@class MyClass; //or #import "MyClass.h"
@interface MyViewController : UIViewController
@end
Now I have to #import "MyClass.h" in my MyViewController.m File.
Advantages : Shorter compile times, less chance of cyclical references; you should definitely get in the habit of doing this if you aren't already.
2. @interface : Used to declare of Class / Interface or Category
Class/ Interface Declaration
Example : File name is "MyClass.h", I have created MyClass using NSObject Base Class
#import <Foundation/Foundation.h>
@interface MyClass : NSObject
@end
Category Declaration
Example : File name is "NSString+MYCustomString.h". I have created MyCustomString Category using NSString Base Class.
#import <Foundation/Foundation.h>
@interface NSString (MYCustomString)
@end
3. @implementation : Used to define a Class / Interface or Category
Class/ Interface Definition
Example : File name is "MyClass.m", I have implemented MyClass using "MyClass.h" header file
#import "MyClass.h"
@implementation MyClass
@end
Category Definition
Example : File name is "NSString+MYCustomString.m". I have implemented MyClass using "MYCustomString.h" header file
#import "NSString+MYCustomString.h"
@implementation NSString (MYCustomString)
@end
4. @end : Used to indicates ends the declaration, definition of Class/ Interface, Category or Protocols.
Example: We can see in every Class/Protocol/Interface/Category like blow code
#import "MyClass.h"
@implementation MyClass
@end
Instance Variable Visibility
5. @public : Declares that instance variables as public access to all classes.
6. @private :Declares that instance variables only available in this class.
7. @protected : Declares that instance variables available in this class and its derived classes as well, it's default property.
8. @package It means the instance variable member is accessible only from the framework in which it is defined.
Example. In "MyClass.h" file
#import <Foundation/Foundation.h>
@interface MyClass : NSObject {
@public
NSString *firstName;
NSString *lastName;
@private
NSString *personalID;
@package
int age;
@protected // this is default
NSString *address;
}
@end
Properties
09. @property : Declares a property of variable with exact behavior of property using property modifiers like strong, weak etc.
Example: In my "MyClass.h" file
#import <Foundation/Foundation.h>
@interface MyClass : NSObject {
}
// define variable property
@property NSString *firstName;
//define variable property with exact behavior
@property (nonatomic, retain) NSString *lastName;
@end
@interface MyClass : NSObject{
float rate;
NSString *name;
}
10. @synthesize: Tells compiler to automatically generate setter and getter methods for the given property in its header file
Example: In my MyClass.m file
#import "MyClass.h"
@implementation MyClass
@synthesize firstName;
@synthesize lastName;
@end
11. @dynamic : directive essentially tells the compiler "don't worry about it, its setter and getter methods are on the way."
So we use dynamic directive in two situations
a. if we are going to write setter and getter ourselves for adding some extra logic
b. or just tells the compiler that the getter and setter methods are implemented not by the class itself
but somewhere else (like the superclass)
Example:
Super class:
@property (nonatomic, retain) NSButton *someButton;
...
@synthesize someButton;
Subclass:
@property (nonatomic, retain) IBOutlet NSButton *someButton;
...
@dynamic someButton;
Protocols
12. @protocol : Marks the start of protocol declaration.
Defines a set of methods to be implemented by any class conforming to the protocol,
as if they were added to the interface of that class.
Example:
@protocol MyProtocol <NSObject>
//declare method here
@end
#import <Foundation/Foundation.h>
@interface MyClass : NSObject
@end
13. @required : Used to declare protocol method implementation is must when a class use adopt this protocol. Protocol methods are required by default.
Example:
@protocol MyProtocol <NSObject>
//this is default (required method)
-(NSString *) getUserName;
@end
#import <Foundation/Foundation.h>
@interface MyClass : NSObject
@end
14. @optional : Used to declare protocol method implementation is optional when a class use adopt this protocol.
Example
@protocol MyProtocol <NSObject>
@required
-(NSString *) getUserName;
@optional
-(NSString *) getUserID;
-(BOOL) isValidUser;
@end
#import <Foundation/Foundation.h>
@interface MyClass : NSObject
@end
Exception Handling
15. @try : defines a block of code that can throw an exception.
16. @catch : define block of code to handle exception thrown by try block, this is usually an NSException object.
17. @finally : defines a block of code that executed whether an exception is thrown or not.
Example:
MyClass *obj = [[MyClass alloc] init];
@try {
[obj noSuchMethod];
}
@catch (NSException *e) {
NSLog(@"The Exception name is %@ and the reason is %@",[e name], [e reason]);
}
@finally {
[obj release];//no use after ARC enabled
}
18. @throw : defines throws an exception object
Example:
NSException* myException = [NSException
exceptionWithName:@"IndexOutOfBoundsException"
reason:@"Attempted to access an array index that is out of bounds"
userInfo:nil];
@throw myException;
// [myException raise]; /* equivalent to throwing the exception, above */
Object Literals
19. @" string " : Declares a content NSString object. Such strings do not need to be retained or released.
Example:
NSString *str = @"This is a constant string.";
20. @42, @3.14, @YES, @'Z' : Returns an NSNumber object initialized with pertinent class constructor
Example
// character literals.
NSNumber *theLetterZ = @'Z'; // equivalent to [NSNumber numberWithChar:'Z']
// integral literals.
NSNumber *fortyTwo = @42; // equivalent to [NSNumber numberWithInt:42]
NSNumber *fortyTwoUnsigned = @42U; // equivalent to [NSNumber numberWithUnsignedInt:42U]
NSNumber *fortyTwoLong = @42L; // equivalent to [NSNumber numberWithLong:42L]
NSNumber *fortyTwoLongLong = @42LL; // equivalent to [NSNumber numberWithLongLong:42LL]
// floating point literals.
NSNumber *piFloat = @3.141592654F; // equivalent to [NSNumber numberWithFloat:3.141592654F]
NSNumber *piDouble = @3.1415926535; // equivalent to [NSNumber numberWithDouble:3.1415926535]
// BOOL literals.
NSNumber *yesNumber = @YES; // equivalent to [NSNumber numberWithBool:YES]
NSNumber *noNumber = @NO; // equivalent to [NSNumber numberWithBool:NO]
21. @[ ] : Returns an NSArray object initialized with the comma-delimited list of objects as its contents.
Example
NSArray *myArray = @[@"one",@"two",@"three"];
is same as
NSArray *myArray = [NSArray arrayWithObjects:@"one",@"two",@"three", nil];
22. @{ } : Returns an NSDictionary object initialized with the specified key-value pairs as its contents, in the format: @{@"someKey" : @"theValue"}.
Example :
NSDictionary *myDictionary = @{@"userName" : @"rdc", @"password":@"testPwd"};
is same as
NSDictionary *myDictionary2 = [NSDictionary dictionaryWithObjectsAndKeys:@"userName", @"rdc", @"password",@"testPwd", nil];
//nil to signify end of objects and keys.
23. @( ) : Dynamically evaluates the boxed expression and returns the appropriate object literal based on its value
Example: In my "MyClass.m" file
#import "MyClass.h"
@implementation MyClass
-(void) boxedExpressions{
// numbers.
NSNumber *smallestInt = @(-INT_MAX - 1); // [NSNumber numberWithInt:(-INT_MAX - 1)]
NSNumber *piOverTwo = @(M_PI / 2); // [NSNumber numberWithDouble:(M_PI / 2)]
// enumerated types.
typedef enum { Red, Green, Blue } Color;
NSNumber *favoriteColor = @(Green); // [NSNumber numberWithInt:((int)Green)]
// strings.
NSString *path = @(getenv("PATH")); // [NSString stringWithUTF8String:(getenv("PATH"))]
NSArray *pathComponents = [path componentsSeparatedByString:@":"];
}
@end
Objective-C Literals
24. @selector ( method_name ) : Returns the selector type 'SEL' of the given Objective-C method. Generates compiler warning if the method isn’t declared or doesn’t exist.
Example:
#import "ViewController.h"
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
SEL aMethodSelector = @selector(aMethod);
[self performSelector:aMethodSelector];
}
-(void)aMethod{
NSLog(@"aMethod called");
}
@end
25. @protocol (protocol_name ) : Returns a Protocol * pointer to the protocol with the specified name.
For example to check if an object conforms to a protocol. You can then cast it to an object conforming to that protocol so that you can call protocol methods on it, without having to know which kind of class the object is:
Protocol *aProtocol = @protocol(ProtocolName);
if ([sender conformsToProtocol:aProtocol])
{
id senderWithProtocol = (id )sender;
BOOL wtf = [senderWithProtocol aProtocolMethod];
}
if ([sender conformsToProtocol:aProtocol])
{
id senderWithProtocol = (id )sender;
BOOL wtf = [senderWithProtocol aProtocolMethod];
}
C Literals
26. @encode ( type_spec) : Returns the character string encoding of a type.
Example:
-(void) aMethod
{
char *enc1 = @encode(int); /* enc1 = "i" */
{
char *enc1 = @encode(int); /* enc1 = "i" */
char *enc2 = @encode(id); /* enc2 = "@" */
char *enc3 = @encode(@selector(aMethod)); /* enc3 = ":" */
/* practical example: */
CGRect rect = CGRectMake(0, 0, 100, 100);
NSValue *v = [NSValue value:&rect withObjCType:@encode(CGRect)];
}
NSValue *v = [NSValue value:&rect withObjCType:@encode(CGRect)];
}
27. @defs ( ) : The @defs directive returns the layout of an Objective-C class.
Example:
struct { @defs( NSObject) }
Optimizations
28. @autoreleasepool { } : create autoreleasepool to dealloc real eased objects when execution complete at the end of block.
If your code contains a tight loop that creates lots of temporary objects, you can use the @autorelease directive to optimize for these short-lived, locally-scoped objects by being more aggressive about how they're deallocated. @autoreleasepool replaces and improves upon the old NSAutoreleasePool, which is significantly slower, and unavailable with ARC.
You should not declare a variable inside the @autoreleasepool block.
The @autoreleasepool is about six times faster than using NSAutoreleasePool, therefore Apple recommends its use even for non-ARC projects.
Example:
-(void) aMethod
{
@autoreleasepool
{
/* code that creates a large number of temporary objects */
}
}
{
@autoreleasepool
{
/* code that creates a large number of temporary objects */
}
}
29. @synchronized { } : Encapsulates code in a mutex lock. It ensures that the block of code and the locked object can only be accessed by one thread at a time.
Example :
-(void) aMethodWithObject:(id)object
{
@synchronized(object)
{
/* code that works with locked object */
}
}
{
@synchronized(object)
{
/* code that works with locked object */
}
}
Compatibility
30. @compatibility_alias : Allows you to define an alias name for an existing class. The first parameter is the alias for a class name, a class with this name must not exist. The second parameter is the name of an existing class that the alias refers to.
Example : in MyClass.h file
#import <Foundation/Foundation.h>
#import "ExistingClassName.h"
@interface MyClass : NSObject
@end
@compatibility_alias AliasClassName ExistingClassName;
No comments:
Post a Comment