![]() |
IOS Streaming Browser 1.0
An IOS streaming browser to stream the display to others or to a projector
|
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