IOS Streaming Browser 1.0
An IOS streaming browser to stream the display to others or to a projector

/Users/willrubel/IOS-Streaming-Browser/IOS-Streaming-Browser/DDLog.h

Go to the documentation of this file.
00001 
00002 #import <Foundation/Foundation.h>
00003 
00004 /**
00005  * Welcome to Cocoa Lumberjack!
00006  * 
00007  * The Google Code page has a wealth of documentation if you have any questions.
00008  * http://code.google.com/p/cocoalumberjack/
00009  * 
00010  * If you're new to the project you may wish to read the "Getting Started" page.
00011  * http://code.google.com/p/cocoalumberjack/wiki/GettingStarted
00012  * 
00013  * Otherwise, here is a quick refresher.
00014  * There are three steps to using the macros:
00015  * 
00016  * Step 1:
00017  * Import the header in your implementation file:
00018  * 
00019  * #import "DDLog.h"
00020  * 
00021  * Step 2:
00022  * Define your logging level in your implementation file:
00023  * 
00024  * // Log levels: off, error, warn, info, verbose
00025  * static const int ddLogLevel = LOG_LEVEL_VERBOSE;
00026  * 
00027  * Step 3:
00028  * Replace your NSLog statements with DDLog statements according to the severity of the message.
00029  * 
00030  * NSLog(@"Fatal error, no dohickey found!"); -> DDLogError(@"Fatal error, no dohickey found!");
00031  * 
00032  * DDLog works exactly the same as NSLog.
00033  * This means you can pass it multiple variables just like NSLog.
00034 **/
00035 
00036 
00037 // Can we use Grand Central Dispatch?
00038 // 
00039 // This question is actually composed of two parts:
00040 // 1. Is it available to the compiler?
00041 // 2. Is it available to the runtime?
00042 // 
00043 // For example, if we are building a universal iPad/iPhone app,
00044 // our base SDK may be iOS 4, but our deployment target would be iOS 3.2.
00045 // In this case we can compile against the GCD libraries (which are available starting with iOS 4),
00046 // but we can only use them at runtime if running on iOS 4 or later.
00047 // If running on an iPad using iOS 3.2, we need to use runtime checks for backwards compatibility.
00048 // 
00049 // The solution is to use a combination of compile-time and run-time macros.
00050 // 
00051 // Note that when the minimum supported SDK supports GCD
00052 // the run-time checks will be compiled out during optimization.
00053 
00054 #if TARGET_OS_IPHONE
00055 
00056   // Compiling for iPod/iPhone/iPad
00057 
00058   #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000 // 4.0 supported
00059   
00060     #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 40000 // 4.0 supported and required
00061 
00062       /**
00063             Sets the flag for whether grand central dispatch is available to YES
00064        **/
00065       #define IS_GCD_AVAILABLE      YES
00066 
00067 
00068       #define GCD_MAYBE_AVAILABLE   1
00069       #define GCD_MAYBE_UNAVAILABLE 0
00070 
00071     #else                                         // 4.0 supported but not required
00072 
00073       #ifndef NSFoundationVersionNumber_iPhoneOS_4_0
00074         #define NSFoundationVersionNumber_iPhoneOS_4_0 751.32
00075       #endif
00076 
00077       #define IS_GCD_AVAILABLE     (NSFoundationVersionNumber >= NSFoundationVersionNumber_iPhoneOS_4_0)
00078       #define GCD_MAYBE_AVAILABLE   1
00079       #define GCD_MAYBE_UNAVAILABLE 1
00080 
00081     #endif
00082 
00083   #else                                        // 4.0 not supported
00084 
00085     /**
00086         Sets the flag for whether grand central dispatch is available to NO
00087      **/
00088     #define IS_GCD_AVAILABLE      NO
00089     #define GCD_MAYBE_AVAILABLE   0
00090     #define GCD_MAYBE_UNAVAILABLE 1
00091 
00092   #endif
00093 
00094 #else
00095 
00096   // Compiling for Mac OS X
00097 
00098   #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 // 10.6 supported
00099   
00100     #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 // 10.6 supported and required
00101 
00102         /**
00103             Sets the flag for whether grand central dispatch is available to YES
00104          **/
00105         #define IS_GCD_AVAILABLE      YES
00106         #define GCD_MAYBE_AVAILABLE   1
00107         #define GCD_MAYBE_UNAVAILABLE 0
00108 
00109     #else                                     // 10.6 supported but not required
00110 
00111       #ifndef NSFoundationVersionNumber10_6
00112         #define NSFoundationVersionNumber10_6 751.00
00113       #endif
00114 
00115       #define IS_GCD_AVAILABLE     (NSFoundationVersionNumber >= NSFoundationVersionNumber10_6)
00116       #define GCD_MAYBE_AVAILABLE   1
00117       #define GCD_MAYBE_UNAVAILABLE 1
00118 
00119     #endif
00120   
00121   #else                                    // 10.6 not supported
00122 
00123     /**
00124         Sets the flag for whether grand central dispatch is available to NO
00125     **/
00126     #define IS_GCD_AVAILABLE      NO
00127     #define GCD_MAYBE_AVAILABLE   0
00128     #define GCD_MAYBE_UNAVAILABLE 1
00129 
00130   #endif
00131 
00132 #endif
00133 
00134 /**
00135 // Uncomment for quick temporary test to see if it builds for older OS targets
00136 #undef IS_GCD_AVAILABLE
00137 #undef GCD_MAYBE_AVAILABLE
00138 #undef GCD_MAYBE_UNAVAILABLE
00139 
00140 #define IS_GCD_AVAILABLE      NO
00141 #define GCD_MAYBE_AVAILABLE   0
00142 #define GCD_MAYBE_UNAVAILABLE 1
00143 **/
00144 
00145 @class DDLogMessage;
00146 
00147 @protocol DDLogger;
00148 @protocol DDLogFormatter;
00149 
00150 /**
00151  * Define our big multiline macros so all the other macros will be easy to read.
00152 **/
00153 
00154 #define LOG_MACRO(isSynchronous, lvl, flg, ctx, fnct, frmt, ...) \
00155   [DDLog log:isSynchronous                                       \
00156        level:lvl                                                 \
00157         flag:flg                                                 \
00158      context:ctx                                                 \
00159         file:__FILE__                                            \
00160     function:fnct                                                \
00161         line:__LINE__                                            \
00162       format:(frmt), ##__VA_ARGS__]
00163 
00164 
00165 #define LOG_OBJC_MACRO(sync, lvl, flg, ctx, frmt, ...) \
00166              LOG_MACRO(sync, lvl, flg, ctx, sel_getName(_cmd), frmt, ##__VA_ARGS__)
00167 
00168 #define LOG_C_MACRO(sync, lvl, flag, ctx, frmt, ...) \
00169           LOG_MACRO(sync, lvl, flg, ctx, __FUNCTION__, frmt, ##__VA_ARGS__)
00170 
00171 #define  SYNC_LOG_OBJC_MACRO(lvl, flg, ctx, frmt, ...) \
00172               LOG_OBJC_MACRO(YES, lvl, flg, ctx, frmt, ##__VA_ARGS__)
00173 
00174 #define ASYNC_LOG_OBJC_MACRO(lvl, flg, ctx, frmt, ...) \
00175               LOG_OBJC_MACRO( NO, lvl, flg, ctx, frmt, ##__VA_ARGS__)
00176 
00177 #define  SYNC_LOG_C_MACRO(lvl, flg, ctx, frmt, ...) \
00178               LOG_C_MACRO(YES, lvl, flg, ctx, frmt, ##__VA_ARGS__)
00179 
00180 #define ASYNC_LOG_C_MACRO(lvl, flg, ctx, frmt, ...) \
00181               LOG_C_MACRO( NO, lvl, flg, ctx, frmt, ##__VA_ARGS__)
00182 
00183 
00184 #define LOG_MAYBE(sync, lvl, flg, ctx, fnct, frmt, ...) \
00185   do { if(lvl & flg) LOG_MACRO(sync, lvl, flg, ctx, fnct, frmt, ##__VA_ARGS__); } while(0)
00186 
00187 #define LOG_OBJC_MAYBE(sync, lvl, flg, ctx, frmt, ...) \
00188              LOG_MAYBE(sync, lvl, flg, ctx, sel_getName(_cmd), frmt, ##__VA_ARGS__)
00189 
00190 #define LOG_C_MAYBE(sync, lvl, flg, ctx, frmt, ...) \
00191           LOG_MAYBE(sync, lvl, flg, ctx, __FUNCTION__, frmt, ##__VA_ARGS__)
00192 
00193 #define  SYNC_LOG_OBJC_MAYBE(lvl, flg, ctx, frmt, ...) \
00194               LOG_OBJC_MAYBE(YES, lvl, flg, ctx, frmt, ##__VA_ARGS__)
00195 
00196 #define ASYNC_LOG_OBJC_MAYBE(lvl, flg, ctx, frmt, ...) \
00197               LOG_OBJC_MAYBE( NO, lvl, flg, ctx, frmt, ##__VA_ARGS__)
00198 
00199 #define  SYNC_LOG_C_MAYBE(lvl, flg, ctx, frmt, ...) \
00200               LOG_C_MAYBE(YES, lvl, flg, ctx, frmt, ##__VA_ARGS__)
00201 
00202 #define ASYNC_LOG_C_MAYBE(lvl, flg, ctx, frmt, ...) \
00203               LOG_C_MAYBE( NO, lvl, flg, ctx, frmt, ##__VA_ARGS__)
00204 
00205 /**
00206  * Define our standard log levels.
00207  * 
00208  * We default to only 4 levels because it makes it easier for beginners
00209  * to make the transition to a logging framework.
00210  * 
00211  * More advanced users may choose to completely customize the levels (and level names) to suite their needs.
00212  * For more information on this see the "Custom Log Levels" page:
00213  * http://code.google.com/p/cocoalumberjack/wiki/CustomLogLevels
00214  * 
00215  * Advanced users may also notice that we're using a bitmask.
00216  * This is to allow for custom fine grained logging:
00217  * http://code.google.com/p/cocoalumberjack/wiki/FineGrainedLogging
00218 **/
00219 
00220 #define LOG_FLAG_ERROR    (1 << 0)  // 0...0001
00221 #define LOG_FLAG_WARN     (1 << 1)  // 0...0010
00222 #define LOG_FLAG_INFO     (1 << 2)  // 0...0100
00223 #define LOG_FLAG_VERBOSE  (1 << 3)  // 0...1000
00224 
00225 #define LOG_LEVEL_OFF     0
00226 #define LOG_LEVEL_ERROR   (LOG_FLAG_ERROR)                                                    // 0...0001
00227 #define LOG_LEVEL_WARN    (LOG_FLAG_ERROR | LOG_FLAG_WARN)                                    // 0...0011
00228 #define LOG_LEVEL_INFO    (LOG_FLAG_ERROR | LOG_FLAG_WARN | LOG_FLAG_INFO)                    // 0...0111
00229 #define LOG_LEVEL_VERBOSE (LOG_FLAG_ERROR | LOG_FLAG_WARN | LOG_FLAG_INFO | LOG_FLAG_VERBOSE) // 0...1111
00230 
00231 #define LOG_ERROR   (ddLogLevel & LOG_FLAG_ERROR)
00232 #define LOG_WARN    (ddLogLevel & LOG_FLAG_WARN)
00233 #define LOG_INFO    (ddLogLevel & LOG_FLAG_INFO)
00234 #define LOG_VERBOSE (ddLogLevel & LOG_FLAG_VERBOSE)
00235 
00236 #define DDLogError(frmt, ...)     SYNC_LOG_OBJC_MAYBE(ddLogLevel, LOG_FLAG_ERROR,   0, frmt, ##__VA_ARGS__)
00237 #define DDLogWarn(frmt, ...)     ASYNC_LOG_OBJC_MAYBE(ddLogLevel, LOG_FLAG_WARN,    0, frmt, ##__VA_ARGS__)
00238 #define DDLogInfo(frmt, ...)     ASYNC_LOG_OBJC_MAYBE(ddLogLevel, LOG_FLAG_INFO,    0, frmt, ##__VA_ARGS__)
00239 #define DDLogVerbose(frmt, ...)  ASYNC_LOG_OBJC_MAYBE(ddLogLevel, LOG_FLAG_VERBOSE, 0, frmt, ##__VA_ARGS__)
00240 
00241 #define DDLogCError(frmt, ...)    SYNC_LOG_C_MAYBE(ddLogLevel, LOG_FLAG_ERROR,   0, frmt, ##__VA_ARGS__)
00242 #define DDLogCWarn(frmt, ...)    ASYNC_LOG_C_MAYBE(ddLogLevel, LOG_FLAG_WARN,    0, frmt, ##__VA_ARGS__)
00243 #define DDLogCInfo(frmt, ...)    ASYNC_LOG_C_MAYBE(ddLogLevel, LOG_FLAG_INFO,    0, frmt, ##__VA_ARGS__)
00244 #define DDLogCVerbose(frmt, ...) ASYNC_LOG_C_MAYBE(ddLogLevel, LOG_FLAG_VERBOSE, 0, frmt, ##__VA_ARGS__)
00245 
00246 /**
00247  * The THIS_FILE macro gives you an NSString of the file name.
00248  * For simplicity and clarity, the file name does not include the full path or file extension.
00249  * 
00250  * For example: DDLogWarn(@"%@: Unable to find thingy", THIS_FILE) -> @"MyViewController: Unable to find thingy"
00251 **/
00252 
00253 NSString *ExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
00254 
00255 #define THIS_FILE (ExtractFileNameWithoutExtension(__FILE__, NO))
00256 
00257 /**
00258  * The THIS_METHOD macro gives you the name of the current objective-c method.
00259  * 
00260  * For example: DDLogWarn(@"%@ - Requires non-nil strings") -> @"setMake:model: requires non-nil strings"
00261  * 
00262  * Note: This does NOT work in straight C functions (non objective-c).
00263  * Instead you should use the predefined __FUNCTION__ macro.
00264 **/
00265 
00266 #define THIS_METHOD NSStringFromSelector(_cmd)
00267 
00268 
00269 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00270 #pragma mark -
00271 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00272 
00273 @interface DDLog : NSObject
00274 
00275 #if GCD_MAYBE_AVAILABLE
00276 
00277 /**
00278  * Provides access to the underlying logging queue.
00279  * This may be helpful to Logger classes for things like thread synchronization.
00280 **/
00281 
00282 + (dispatch_queue_t)loggingQueue;
00283 
00284 #endif
00285 
00286 #if GCD_MAYBE_UNAVAILABLE
00287 
00288 /**
00289  * Provides access to the underlying logging thread.
00290  * This may be helpful to Logger classes for things like thread synchronization.
00291 **/
00292 
00293 + (NSThread *)loggingThread;
00294 
00295 #endif
00296 
00297 /**
00298  * Logging Primitive.
00299  * 
00300  * This method is used by the macros above.
00301  * It is suggested you stick with the macros as they're easier to use.
00302 **/
00303 
00304 + (void)log:(BOOL)synchronous
00305       level:(int)level
00306        flag:(int)flag
00307     context:(int)context
00308        file:(const char *)file
00309    function:(const char *)function
00310        line:(int)line
00311      format:(NSString *)format, ...;
00312 
00313 /**
00314  * Since logging can be asynchronous, there may be times when you want to flush the logs.
00315  * The framework invokes this automatically when the application quits.
00316 **/
00317 
00318 + (void)flushLog;
00319 
00320 /** 
00321  * Loggers
00322  * 
00323  * If you want your log statements to go somewhere,
00324  * you should create and add a logger.
00325 **/
00326 
00327 + (void)addLogger:(id <DDLogger>)logger;
00328 + (void)removeLogger:(id <DDLogger>)logger;
00329 
00330 + (void)removeAllLoggers;
00331 
00332 /**
00333  * Registered Dynamic Logging
00334  * 
00335  * These methods allow you to obtain a list of classes that are using registered dynamic logging,
00336  * and also provides methods to get and set their log level during run time.
00337 **/
00338 
00339 /**
00340     Class method
00341 **/
00342 + (NSArray *)registeredClasses;
00343 
00344 /**
00345     Class method
00346     returns NSArray
00347 **/
00348 + (NSArray *)registeredClassNames;
00349 
00350 /**
00351     Class method
00352     param Class
00353     returns int
00354 **/
00355 + (int)logLevelForClass:(Class)aClass;
00356 
00357 /**
00358     Class method
00359     param NSString
00360     returns int
00361 **/
00362 + (int)logLevelForClassWithName:(NSString *)aClassName;
00363 
00364 /**
00365     Class method
00366     param int
00367     param Class
00368 **/
00369 + (void)setLogLevel:(int)logLevel forClass:(Class)aClass;
00370 
00371 /**
00372     Class method
00373     param int
00374     param NSString
00375 **/
00376 + (void)setLogLevel:(int)logLevel forClassWithName:(NSString *)aClassName;
00377 
00378 @end
00379 
00380 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00381 #pragma mark -
00382 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00383 
00384 @protocol DDLogger <NSObject>
00385 @required
00386 
00387 
00388 /**
00389     param DDLogMessage
00390 **/
00391 - (void)logMessage:(DDLogMessage *)logMessage;
00392 
00393 
00394 /**
00395     Formatters may optionally be added to any logger.   If no formatter is set, the logger simply logs the message as it is given in logMessage.  Or it may use its own built in formatting style.
00396     returns id <DDLogFormatter>
00397 **/
00398 - (id <DDLogFormatter>)logFormatter;
00399 
00400 /**
00401     param id <DDLogFormatter>
00402 **/
00403 - (void)setLogFormatter:(id <DDLogFormatter>)formatter;
00404 
00405 @optional
00406 
00407 /**
00408  * Since logging is asynchronous, adding and removing loggers is also asynchronous.
00409  * In other words, the loggers are added and removed at appropriate times with regards to log messages.
00410  * 
00411  * - Loggers will not receive log messages that were executed prior to when they were added.
00412  * - Loggers will not receive log messages that were executed after they were removed.
00413  * 
00414  * These methods are executed in the logging thread/queue.
00415  * This is the same thread/queue that will execute every logMessage: invocation.
00416  * Loggers may use these methods for thread synchronization or other setup/teardown tasks.
00417 **/
00418 
00419 - (void)didAddLogger;
00420 
00421 /**
00422  
00423 **/
00424 - (void)willRemoveLogger;
00425 
00426 #if GCD_MAYBE_AVAILABLE
00427 
00428 /**
00429  * When Grand Central Dispatch is available
00430  * each logger is executed concurrently with respect to the other loggers.
00431  * Thus, a dedicated dispatch queue is used for each logger.
00432  * Logger implementations may optionally choose to provide their own dispatch queue.
00433 **/
00434 - (dispatch_queue_t)loggerQueue;
00435 
00436 /**
00437  * If the logger implementation does not choose to provide its own queue,
00438  * one will automatically be created for it.
00439  * The created queue will receive its name from this method.
00440  * This may be helpful for debugging or profiling reasons.
00441 **/
00442 - (NSString *)loggerName;
00443 
00444 #endif
00445 
00446 @end
00447 
00448 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00449 #pragma mark -
00450 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00451 
00452 @protocol DDLogFormatter <NSObject>
00453 @required
00454 
00455 /**
00456  * Formatters may optionally be added to any logger.
00457  * This allows for increased flexibility in the logging environment.
00458  * For example, log messages for log files may be formatted differently than log messages for the console.
00459  * 
00460  * For more information about formatters, see the "Custom Formatters" page:
00461  * http://code.google.com/p/cocoalumberjack/wiki/CustomFormatters
00462  * 
00463  * The formatter may also optionally filter the log message by returning nil,
00464  * in which case the logger will not log the message.
00465 **/
00466 
00467 - (NSString *)formatLogMessage:(DDLogMessage *)logMessage;
00468 
00469 @end
00470 
00471 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00472 #pragma mark -
00473 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00474 
00475 @protocol DDRegisteredDynamicLogging
00476 
00477 /**
00478  * Implement these methods to allow a file's log level to be managed from a central location.
00479  * 
00480  * This is useful if you'd like to be able to change log levels for various parts
00481  * of your code from within the running application.
00482  * 
00483  * Imagine pulling up the settings for your application,
00484  * and being able to configure the logging level on a per file basis.
00485  * 
00486  * The implementation can be very straight-forward:
00487  * 
00488  * + (int)ddLogLevel
00489  * {
00490  *     return ddLogLevel;
00491  * }
00492  *  
00493  * + (void)ddSetLogLevel:(int)logLevel
00494  * {
00495  *     ddLogLevel = logLevel;
00496  * }
00497 **/
00498 
00499 /**
00500     Class method
00501     returns int
00502 **/
00503 + (int)ddLogLevel;
00504 
00505 /**
00506     Class method
00507     param int
00508 **/
00509 + (void)ddSetLogLevel:(int)logLevel;
00510 
00511 @end
00512 
00513 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00514 #pragma mark -
00515 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00516 
00517 /**
00518  * The DDLogMessage class encapsulates information about the log message.
00519  * If you write custom loggers or formatters, you will be dealing with objects of this class.
00520 **/
00521 @interface DDLogMessage : NSObject
00522 {
00523 
00524 // The public variables below can be accessed directly (for speed).
00525 // For example: logMessage->logLevel
00526         
00527 @public
00528     
00529     /**
00530      
00531     **/
00532         int logLevel;
00533 
00534     /**
00535      
00536      **/        
00537     int logFlag;
00538     
00539     /**
00540      
00541      **/
00542         int logContext;
00543     
00544     /**
00545      
00546      **/
00547         NSString *logMsg;
00548     
00549     /**
00550      
00551      **/
00552         NSDate *timestamp;
00553     
00554     /**
00555      
00556      **/
00557         const char *file;
00558     
00559     /**
00560      
00561      **/
00562         const char *function;
00563     
00564     /**
00565      
00566      **/
00567         int lineNumber;
00568     
00569     /**
00570      
00571      **/
00572         mach_port_t machThreadID;
00573 
00574 // The private variables below are only calculated if needed.
00575 // You should use the public methods to access this information.
00576         
00577 @private
00578     
00579     /**
00580      
00581      **/
00582         NSString *threadID;
00583     
00584     /**
00585      
00586      **/
00587         NSString *fileName;
00588     
00589     /**
00590      
00591      **/
00592         NSString *methodName;
00593 }
00594 
00595 /**
00596 // The initializer is somewhat reserved for internal use.
00597 // However, if you find need to manually create logMessage objects,
00598 // there is one thing you should be aware of.
00599 // The initializer expects the file and function parameters to be string literals.
00600 // That is, it expects the given strings to exist for the duration of the object's lifetime,
00601 // and it expects the given strings to be immutable.
00602 // In other words, it does not copy these strings, it simply points to them.
00603 **/
00604 - (id)initWithLogMsg:(NSString *)logMsg
00605                level:(int)logLevel
00606                 flag:(int)logFlag
00607              context:(int)logContext
00608                 file:(const char *)file
00609             function:(const char *)function
00610                 line:(int)line;
00611 
00612 /**
00613  * Returns the threadID as it appears in NSLog.
00614  * That is, it is a hexadecimal value which is calculated from the machThreadID.
00615  returns NSSTring
00616 **/
00617 - (NSString *)threadID;
00618 
00619 /**
00620  * Convenience method to get just the file name, as the file variable is generally the full file path.
00621  * This method does not include the file extension, which is generally unwanted for logging purposes.
00622     returns NSString
00623 **/
00624 - (NSString *)fileName;
00625 
00626 /**
00627  * Returns the function variable in NSString form.
00628     returns NSString
00629 **/
00630 - (NSString *)methodName;
00631 
00632 @end
00633 
00634 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00635 #pragma mark -
00636 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00637 
00638 /**
00639  * The DDLogger protocol specifies that an optional formatter can be added to a logger.
00640  * Most (but not all) loggers will want to support formatters.
00641  * 
00642  * However, writting getters and setters in a thread safe manner,
00643  * while still maintaining maximum speed for the logging process, is a difficult task.
00644  * 
00645  * To do it right, the implementation of the getter/setter has strict requiremenets:
00646  * - Must NOT require the logMessage method to acquire a lock.
00647  * - Must NOT require the logMessage method to access an atomic property (also a lock of sorts).
00648  * 
00649  * To simplify things, an abstract logger is provided that implements the getter and setter.
00650  * 
00651  * Logger implementations may simply extend this class,
00652  * and they can ACCESS THE FORMATTER VARIABLE DIRECTLY from within their logMessage method!
00653 **/
00654 
00655 @interface DDAbstractLogger : NSObject <DDLogger>
00656 {
00657         id <DDLogFormatter> formatter;
00658         
00659 #if GCD_MAYBE_AVAILABLE
00660         dispatch_queue_t loggerQueue;
00661 #endif
00662 }
00663 
00664 /**
00665  
00666 **/
00667 - (id <DDLogFormatter>)logFormatter;
00668 
00669 /**
00670  
00671 **/
00672 - (void)setLogFormatter:(id <DDLogFormatter>)formatter;
00673 
00674 @end
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Properties Defines