motion-yapper 0.0.3 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (294) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +3 -1
  4. data/lib/yapper.rb +3 -3
  5. data/lib/yapper/db.rb +61 -4
  6. data/lib/yapper/document/persistence.rb +4 -0
  7. data/lib/yapper/document/selection.rb +13 -0
  8. data/lib/yapper/version.rb +1 -1
  9. data/motion-yapper.gemspec +1 -1
  10. data/spec/integration/search_spec.rb +111 -0
  11. data/vendor/Podfile.lock +11 -7
  12. data/vendor/YapDatabaseRubyMotion/YapDatabaseRubyMotion.bridgesupport +16 -2
  13. data/vendor/YapDatabaseRubyMotion/YapDatabaseRubyMotion.h +10 -7
  14. data/vendor/YapDatabaseRubyMotion/YapDatabaseRubyMotion.m +20 -2
  15. metadata +19 -297
  16. data/vendor/Pods/.build/libPods-CocoaLumberjack.a +0 -0
  17. data/vendor/Pods/.build/libPods-NSData+MD5Digest.a +0 -0
  18. data/vendor/Pods/.build/libPods-YapDatabase.a +0 -0
  19. data/vendor/Pods/.build/libPods.a +0 -0
  20. data/vendor/Pods/BuildHeaders/CocoaLumberjack/DDASLLogger.h +0 -41
  21. data/vendor/Pods/BuildHeaders/CocoaLumberjack/DDAbstractDatabaseLogger.h +0 -102
  22. data/vendor/Pods/BuildHeaders/CocoaLumberjack/DDContextFilterLogFormatter.h +0 -63
  23. data/vendor/Pods/BuildHeaders/CocoaLumberjack/DDDispatchQueueLogFormatter.h +0 -128
  24. data/vendor/Pods/BuildHeaders/CocoaLumberjack/DDFileLogger.h +0 -369
  25. data/vendor/Pods/BuildHeaders/CocoaLumberjack/DDLog+LOGV.h +0 -99
  26. data/vendor/Pods/BuildHeaders/CocoaLumberjack/DDLog.h +0 -634
  27. data/vendor/Pods/BuildHeaders/CocoaLumberjack/DDMultiFormatter.h +0 -30
  28. data/vendor/Pods/BuildHeaders/CocoaLumberjack/DDTTYLogger.h +0 -181
  29. data/vendor/Pods/BuildHeaders/NSData+MD5Digest/NSData+MD5Digest.h +0 -18
  30. data/vendor/Pods/BuildHeaders/YapDatabase/NSDictionary+YapDatabase.h +0 -8
  31. data/vendor/Pods/BuildHeaders/YapDatabase/YapCache.h +0 -91
  32. data/vendor/Pods/BuildHeaders/YapDatabase/YapCollectionKey.h +0 -23
  33. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabase.h +0 -547
  34. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseConnection.h +0 -449
  35. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseConnectionState.h +0 -29
  36. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseDefaults.h +0 -37
  37. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseExtension.h +0 -15
  38. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseExtensionConnection.h +0 -11
  39. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseExtensionPrivate.h +0 -444
  40. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseExtensionTransaction.h +0 -11
  41. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFilteredView.h +0 -81
  42. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFilteredViewConnection.h +0 -12
  43. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFilteredViewPrivate.h +0 -17
  44. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFilteredViewTransaction.h +0 -39
  45. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFilteredViewTypes.h +0 -32
  46. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFullTextSearch.h +0 -89
  47. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFullTextSearchConnection.h +0 -32
  48. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFullTextSearchPrivate.h +0 -77
  49. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFullTextSearchSnippetOptions.h +0 -79
  50. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseFullTextSearchTransaction.h +0 -68
  51. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseLogging.h +0 -158
  52. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseManager.h +0 -17
  53. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabasePrivate.h +0 -446
  54. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseQuery.h +0 -42
  55. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseRelationship.h +0 -35
  56. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseRelationshipConnection.h +0 -29
  57. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseRelationshipEdge.h +0 -163
  58. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseRelationshipEdgePrivate.h +0 -79
  59. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseRelationshipNode.h +0 -99
  60. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseRelationshipOptions.h +0 -59
  61. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseRelationshipPrivate.h +0 -125
  62. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseRelationshipTransaction.h +0 -384
  63. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseSecondaryIndex.h +0 -149
  64. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseSecondaryIndexConnection.h +0 -33
  65. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseSecondaryIndexPrivate.h +0 -83
  66. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseSecondaryIndexSetup.h +0 -33
  67. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseSecondaryIndexSetupPrivate.h +0 -18
  68. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseSecondaryIndexTransaction.h +0 -58
  69. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseStatement.h +0 -13
  70. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseString.h +0 -121
  71. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseTransaction.h +0 -651
  72. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseView.h +0 -127
  73. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewChange.h +0 -272
  74. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewChangePrivate.h +0 -94
  75. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewConnection.h +0 -116
  76. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewMappings.h +0 -842
  77. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewMappingsPrivate.h +0 -72
  78. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewOptions.h +0 -63
  79. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewPage.h +0 -36
  80. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewPageMetadata.h +0 -27
  81. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewPrivate.h +0 -170
  82. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewRangeOptions.h +0 -330
  83. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewRangeOptionsPrivate.h +0 -17
  84. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewTransaction.h +0 -498
  85. data/vendor/Pods/BuildHeaders/YapDatabase/YapDatabaseViewTypes.h +0 -99
  86. data/vendor/Pods/BuildHeaders/YapDatabase/YapMemoryTable.h +0 -74
  87. data/vendor/Pods/BuildHeaders/YapDatabase/YapNull.h +0 -17
  88. data/vendor/Pods/BuildHeaders/YapDatabase/YapSet.h +0 -41
  89. data/vendor/Pods/BuildHeaders/YapDatabase/YapTouch.h +0 -15
  90. data/vendor/Pods/CocoaLumberjack/LICENSE.txt +0 -18
  91. data/vendor/Pods/CocoaLumberjack/Lumberjack/DDASLLogger.h +0 -41
  92. data/vendor/Pods/CocoaLumberjack/Lumberjack/DDASLLogger.m +0 -100
  93. data/vendor/Pods/CocoaLumberjack/Lumberjack/DDAbstractDatabaseLogger.h +0 -102
  94. data/vendor/Pods/CocoaLumberjack/Lumberjack/DDAbstractDatabaseLogger.m +0 -727
  95. data/vendor/Pods/CocoaLumberjack/Lumberjack/DDFileLogger.h +0 -369
  96. data/vendor/Pods/CocoaLumberjack/Lumberjack/DDFileLogger.m +0 -1539
  97. data/vendor/Pods/CocoaLumberjack/Lumberjack/DDLog+LOGV.h +0 -99
  98. data/vendor/Pods/CocoaLumberjack/Lumberjack/DDLog.h +0 -634
  99. data/vendor/Pods/CocoaLumberjack/Lumberjack/DDLog.m +0 -1208
  100. data/vendor/Pods/CocoaLumberjack/Lumberjack/DDTTYLogger.h +0 -181
  101. data/vendor/Pods/CocoaLumberjack/Lumberjack/DDTTYLogger.m +0 -1520
  102. data/vendor/Pods/CocoaLumberjack/Lumberjack/Extensions/DDContextFilterLogFormatter.h +0 -63
  103. data/vendor/Pods/CocoaLumberjack/Lumberjack/Extensions/DDContextFilterLogFormatter.m +0 -191
  104. data/vendor/Pods/CocoaLumberjack/Lumberjack/Extensions/DDDispatchQueueLogFormatter.h +0 -128
  105. data/vendor/Pods/CocoaLumberjack/Lumberjack/Extensions/DDDispatchQueueLogFormatter.m +0 -253
  106. data/vendor/Pods/CocoaLumberjack/Lumberjack/Extensions/DDMultiFormatter.h +0 -30
  107. data/vendor/Pods/CocoaLumberjack/Lumberjack/Extensions/DDMultiFormatter.m +0 -127
  108. data/vendor/Pods/CocoaLumberjack/Lumberjack/Extensions/README.txt +0 -7
  109. data/vendor/Pods/CocoaLumberjack/README.markdown +0 -74
  110. data/vendor/Pods/Headers/CocoaLumberjack/DDASLLogger.h +0 -41
  111. data/vendor/Pods/Headers/CocoaLumberjack/DDAbstractDatabaseLogger.h +0 -102
  112. data/vendor/Pods/Headers/CocoaLumberjack/DDContextFilterLogFormatter.h +0 -63
  113. data/vendor/Pods/Headers/CocoaLumberjack/DDDispatchQueueLogFormatter.h +0 -128
  114. data/vendor/Pods/Headers/CocoaLumberjack/DDFileLogger.h +0 -369
  115. data/vendor/Pods/Headers/CocoaLumberjack/DDLog+LOGV.h +0 -99
  116. data/vendor/Pods/Headers/CocoaLumberjack/DDLog.h +0 -634
  117. data/vendor/Pods/Headers/CocoaLumberjack/DDMultiFormatter.h +0 -30
  118. data/vendor/Pods/Headers/CocoaLumberjack/DDTTYLogger.h +0 -181
  119. data/vendor/Pods/Headers/NSData+MD5Digest/NSData+MD5Digest.h +0 -18
  120. data/vendor/Pods/Headers/YapDatabase/YapCollectionKey.h +0 -23
  121. data/vendor/Pods/Headers/YapDatabase/YapDatabase.h +0 -547
  122. data/vendor/Pods/Headers/YapDatabase/YapDatabaseConnection.h +0 -449
  123. data/vendor/Pods/Headers/YapDatabase/YapDatabaseExtension.h +0 -15
  124. data/vendor/Pods/Headers/YapDatabase/YapDatabaseExtensionConnection.h +0 -11
  125. data/vendor/Pods/Headers/YapDatabase/YapDatabaseExtensionTransaction.h +0 -11
  126. data/vendor/Pods/Headers/YapDatabase/YapDatabaseFilteredView.h +0 -81
  127. data/vendor/Pods/Headers/YapDatabase/YapDatabaseFilteredViewConnection.h +0 -12
  128. data/vendor/Pods/Headers/YapDatabase/YapDatabaseFilteredViewTransaction.h +0 -39
  129. data/vendor/Pods/Headers/YapDatabase/YapDatabaseFilteredViewTypes.h +0 -32
  130. data/vendor/Pods/Headers/YapDatabase/YapDatabaseFullTextSearch.h +0 -89
  131. data/vendor/Pods/Headers/YapDatabase/YapDatabaseFullTextSearchConnection.h +0 -32
  132. data/vendor/Pods/Headers/YapDatabase/YapDatabaseFullTextSearchSnippetOptions.h +0 -79
  133. data/vendor/Pods/Headers/YapDatabase/YapDatabaseFullTextSearchTransaction.h +0 -68
  134. data/vendor/Pods/Headers/YapDatabase/YapDatabaseQuery.h +0 -42
  135. data/vendor/Pods/Headers/YapDatabase/YapDatabaseRelationship.h +0 -35
  136. data/vendor/Pods/Headers/YapDatabase/YapDatabaseRelationshipConnection.h +0 -29
  137. data/vendor/Pods/Headers/YapDatabase/YapDatabaseRelationshipEdge.h +0 -163
  138. data/vendor/Pods/Headers/YapDatabase/YapDatabaseRelationshipNode.h +0 -99
  139. data/vendor/Pods/Headers/YapDatabase/YapDatabaseRelationshipOptions.h +0 -59
  140. data/vendor/Pods/Headers/YapDatabase/YapDatabaseRelationshipTransaction.h +0 -384
  141. data/vendor/Pods/Headers/YapDatabase/YapDatabaseSecondaryIndex.h +0 -149
  142. data/vendor/Pods/Headers/YapDatabase/YapDatabaseSecondaryIndexConnection.h +0 -33
  143. data/vendor/Pods/Headers/YapDatabase/YapDatabaseSecondaryIndexSetup.h +0 -33
  144. data/vendor/Pods/Headers/YapDatabase/YapDatabaseSecondaryIndexTransaction.h +0 -58
  145. data/vendor/Pods/Headers/YapDatabase/YapDatabaseTransaction.h +0 -651
  146. data/vendor/Pods/Headers/YapDatabase/YapDatabaseView.h +0 -127
  147. data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewChange.h +0 -272
  148. data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewConnection.h +0 -116
  149. data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewMappings.h +0 -842
  150. data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewOptions.h +0 -63
  151. data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewRangeOptions.h +0 -330
  152. data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewTransaction.h +0 -498
  153. data/vendor/Pods/Headers/YapDatabase/YapDatabaseViewTypes.h +0 -99
  154. data/vendor/Pods/Headers/YapDatabase/YapSet.h +0 -41
  155. data/vendor/Pods/Headers/____Pods-CocoaLumberjack-prefix.h +0 -7
  156. data/vendor/Pods/Headers/____Pods-NSData+MD5Digest-prefix.h +0 -5
  157. data/vendor/Pods/Headers/____Pods-YapDatabase-prefix.h +0 -5
  158. data/vendor/Pods/Headers/____Pods-environment.h +0 -38
  159. data/vendor/Pods/Manifest.lock +0 -22
  160. data/vendor/Pods/NSData+MD5Digest/NSData+MD5Digest/NSData+MD5Digest.h +0 -18
  161. data/vendor/Pods/NSData+MD5Digest/NSData+MD5Digest/NSData+MD5Digest.m +0 -39
  162. data/vendor/Pods/NSData+MD5Digest/README.md +0 -11
  163. data/vendor/Pods/Pods-CocoaLumberjack-Private.xcconfig +0 -5
  164. data/vendor/Pods/Pods-CocoaLumberjack-dummy.m +0 -5
  165. data/vendor/Pods/Pods-CocoaLumberjack-prefix.pch +0 -7
  166. data/vendor/Pods/Pods-CocoaLumberjack.xcconfig +0 -0
  167. data/vendor/Pods/Pods-NSData+MD5Digest-Private.xcconfig +0 -5
  168. data/vendor/Pods/Pods-NSData+MD5Digest-dummy.m +0 -5
  169. data/vendor/Pods/Pods-NSData+MD5Digest-prefix.pch +0 -5
  170. data/vendor/Pods/Pods-NSData+MD5Digest.xcconfig +0 -0
  171. data/vendor/Pods/Pods-YapDatabase-Private.xcconfig +0 -5
  172. data/vendor/Pods/Pods-YapDatabase-dummy.m +0 -5
  173. data/vendor/Pods/Pods-YapDatabase-prefix.pch +0 -5
  174. data/vendor/Pods/Pods-YapDatabase.xcconfig +0 -1
  175. data/vendor/Pods/Pods-acknowledgements.markdown +0 -59
  176. data/vendor/Pods/Pods-acknowledgements.plist +0 -97
  177. data/vendor/Pods/Pods-dummy.m +0 -5
  178. data/vendor/Pods/Pods-environment.h +0 -38
  179. data/vendor/Pods/Pods-resources.sh +0 -68
  180. data/vendor/Pods/Pods.xcconfig +0 -5
  181. data/vendor/Pods/Pods.xcodeproj/project.pbxproj +0 -4807
  182. data/vendor/Pods/Pods.xcodeproj/xcuserdata/kareemk.xcuserdatad/xcschemes/Pods-CocoaLumberjack.xcscheme +0 -59
  183. data/vendor/Pods/Pods.xcodeproj/xcuserdata/kareemk.xcuserdatad/xcschemes/Pods-NSData+MD5Digest.xcscheme +0 -59
  184. data/vendor/Pods/Pods.xcodeproj/xcuserdata/kareemk.xcuserdatad/xcschemes/Pods-YapDatabase.xcscheme +0 -59
  185. data/vendor/Pods/Pods.xcodeproj/xcuserdata/kareemk.xcuserdatad/xcschemes/Pods.xcscheme +0 -59
  186. data/vendor/Pods/Pods.xcodeproj/xcuserdata/kareemk.xcuserdatad/xcschemes/xcschememanagement.plist +0 -31
  187. data/vendor/Pods/YapDatabase/LICENSE.txt +0 -18
  188. data/vendor/Pods/YapDatabase/README.md +0 -32
  189. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FilteredViews/Internal/YapDatabaseFilteredViewPrivate.h +0 -17
  190. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredView.h +0 -81
  191. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredView.m +0 -159
  192. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredViewConnection.h +0 -12
  193. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredViewConnection.m +0 -41
  194. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredViewTransaction.h +0 -39
  195. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredViewTransaction.m +0 -1235
  196. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FilteredViews/YapDatabaseFilteredViewTypes.h +0 -32
  197. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/Internal/YapDatabaseFullTextSearchPrivate.h +0 -77
  198. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearch.h +0 -89
  199. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearch.m +0 -146
  200. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearchConnection.h +0 -32
  201. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearchConnection.m +0 -298
  202. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearchSnippetOptions.h +0 -79
  203. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearchSnippetOptions.m +0 -95
  204. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearchTransaction.h +0 -68
  205. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/FullTextSearch/YapDatabaseFullTextSearchTransaction.m +0 -1403
  206. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Protocol/Internal/YapDatabaseExtensionPrivate.h +0 -444
  207. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Protocol/YapDatabaseExtension.h +0 -15
  208. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Protocol/YapDatabaseExtension.m +0 -83
  209. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Protocol/YapDatabaseExtensionConnection.h +0 -11
  210. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Protocol/YapDatabaseExtensionConnection.m +0 -46
  211. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Protocol/YapDatabaseExtensionTransaction.h +0 -11
  212. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Protocol/YapDatabaseExtensionTransaction.m +0 -204
  213. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Relationships/Internal/YapDatabaseRelationshipEdgePrivate.h +0 -79
  214. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Relationships/Internal/YapDatabaseRelationshipPrivate.h +0 -125
  215. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Relationships/YapDatabaseRelationship.h +0 -35
  216. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Relationships/YapDatabaseRelationship.m +0 -129
  217. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Relationships/YapDatabaseRelationshipConnection.h +0 -29
  218. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Relationships/YapDatabaseRelationshipConnection.m +0 -802
  219. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Relationships/YapDatabaseRelationshipEdge.h +0 -163
  220. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Relationships/YapDatabaseRelationshipEdge.m +0 -408
  221. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Relationships/YapDatabaseRelationshipNode.h +0 -99
  222. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Relationships/YapDatabaseRelationshipOptions.h +0 -59
  223. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Relationships/YapDatabaseRelationshipOptions.m +0 -29
  224. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Relationships/YapDatabaseRelationshipTransaction.h +0 -384
  225. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Relationships/YapDatabaseRelationshipTransaction.m +0 -5254
  226. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/Internal/YapDatabaseSecondaryIndexPrivate.h +0 -83
  227. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/Internal/YapDatabaseSecondaryIndexSetupPrivate.h +0 -18
  228. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndex.h +0 -149
  229. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndex.m +0 -161
  230. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndexConnection.h +0 -33
  231. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndexConnection.m +0 -331
  232. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndexSetup.h +0 -33
  233. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndexSetup.m +0 -245
  234. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndexTransaction.h +0 -58
  235. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/SecondaryIndex/YapDatabaseSecondaryIndexTransaction.m +0 -1269
  236. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewChangePrivate.h +0 -94
  237. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewMappingsPrivate.h +0 -72
  238. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewPage.h +0 -36
  239. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewPage.mm +0 -296
  240. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewPageMetadata.h +0 -27
  241. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewPageMetadata.m +0 -28
  242. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewPrivate.h +0 -170
  243. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Internal/YapDatabaseViewRangeOptionsPrivate.h +0 -17
  244. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Utilities/YapDatabaseViewChange.h +0 -272
  245. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Utilities/YapDatabaseViewChange.m +0 -2500
  246. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Utilities/YapDatabaseViewMappings.h +0 -842
  247. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Utilities/YapDatabaseViewMappings.m +0 -1714
  248. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Utilities/YapDatabaseViewRangeOptions.h +0 -330
  249. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/Utilities/YapDatabaseViewRangeOptions.m +0 -141
  250. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseView.h +0 -127
  251. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseView.m +0 -194
  252. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseViewConnection.h +0 -116
  253. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseViewConnection.m +0 -888
  254. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseViewOptions.h +0 -63
  255. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseViewOptions.m +0 -27
  256. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseViewTransaction.h +0 -498
  257. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseViewTransaction.m +0 -4986
  258. data/vendor/Pods/YapDatabase/YapDatabase/Extensions/Views/YapDatabaseViewTypes.h +0 -99
  259. data/vendor/Pods/YapDatabase/YapDatabase/Internal/NSDictionary+YapDatabase.h +0 -8
  260. data/vendor/Pods/YapDatabase/YapDatabase/Internal/NSDictionary+YapDatabase.m +0 -19
  261. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapCache.h +0 -91
  262. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapCache.m +0 -465
  263. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseConnectionState.h +0 -29
  264. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseConnectionState.m +0 -48
  265. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseDefaults.h +0 -37
  266. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseDefaults.m +0 -83
  267. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseLogging.h +0 -158
  268. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseLogging.m +0 -73
  269. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseManager.h +0 -17
  270. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseManager.m +0 -56
  271. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabasePrivate.h +0 -446
  272. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseStatement.h +0 -13
  273. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseStatement.m +0 -26
  274. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapDatabaseString.h +0 -121
  275. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapMemoryTable.h +0 -74
  276. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapMemoryTable.m +0 -603
  277. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapNull.h +0 -17
  278. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapNull.m +0 -35
  279. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapTouch.h +0 -15
  280. data/vendor/Pods/YapDatabase/YapDatabase/Internal/YapTouch.m +0 -31
  281. data/vendor/Pods/YapDatabase/YapDatabase/Utilities/YapCollectionKey.h +0 -23
  282. data/vendor/Pods/YapDatabase/YapDatabase/Utilities/YapCollectionKey.m +0 -199
  283. data/vendor/Pods/YapDatabase/YapDatabase/Utilities/YapDatabaseQuery.h +0 -42
  284. data/vendor/Pods/YapDatabase/YapDatabase/Utilities/YapDatabaseQuery.m +0 -96
  285. data/vendor/Pods/YapDatabase/YapDatabase/Utilities/YapSet.h +0 -41
  286. data/vendor/Pods/YapDatabase/YapDatabase/Utilities/YapSet.m +0 -82
  287. data/vendor/Pods/YapDatabase/YapDatabase/YapDatabase.h +0 -547
  288. data/vendor/Pods/YapDatabase/YapDatabase/YapDatabase.m +0 -2013
  289. data/vendor/Pods/YapDatabase/YapDatabase/YapDatabaseConnection.h +0 -449
  290. data/vendor/Pods/YapDatabase/YapDatabase/YapDatabaseConnection.m +0 -4046
  291. data/vendor/Pods/YapDatabase/YapDatabase/YapDatabaseTransaction.h +0 -651
  292. data/vendor/Pods/YapDatabase/YapDatabase/YapDatabaseTransaction.m +0 -5602
  293. data/vendor/Pods/build-iPhoneSimulator/Pods.bridgesupport +0 -3172
  294. data/vendor/Pods/build-iPhoneSimulator/libPods.a +0 -0
@@ -1,1208 +0,0 @@
1
- #import "DDLog.h"
2
-
3
- #import <pthread.h>
4
- #import <objc/runtime.h>
5
- #import <mach/mach_host.h>
6
- #import <mach/host_info.h>
7
- #import <libkern/OSAtomic.h>
8
- #import <Availability.h>
9
- #if TARGET_OS_IPHONE
10
- #import <UIKit/UIDevice.h>
11
- #endif
12
-
13
- /**
14
- * Welcome to Cocoa Lumberjack!
15
- *
16
- * The project page has a wealth of documentation if you have any questions.
17
- * https://github.com/CocoaLumberjack/CocoaLumberjack
18
- *
19
- * If you're new to the project you may wish to read the "Getting Started" wiki.
20
- * https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/GettingStarted
21
- *
22
- **/
23
-
24
- #if ! __has_feature(objc_arc)
25
- #warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
26
- #endif
27
-
28
- // We probably shouldn't be using DDLog() statements within the DDLog implementation.
29
- // But we still want to leave our log statements for any future debugging,
30
- // and to allow other developers to trace the implementation (which is a great learning tool).
31
- //
32
- // So we use a primitive logging macro around NSLog.
33
- // We maintain the NS prefix on the macros to be explicit about the fact that we're using NSLog.
34
-
35
- #define DD_DEBUG NO
36
-
37
- #define NSLogDebug(frmt, ...) do{ if(DD_DEBUG) NSLog((frmt), ##__VA_ARGS__); } while(0)
38
-
39
- // Specifies the maximum queue size of the logging thread.
40
- //
41
- // Since most logging is asynchronous, its possible for rogue threads to flood the logging queue.
42
- // That is, to issue an abundance of log statements faster than the logging thread can keepup.
43
- // Typically such a scenario occurs when log statements are added haphazardly within large loops,
44
- // but may also be possible if relatively slow loggers are being used.
45
- //
46
- // This property caps the queue size at a given number of outstanding log statements.
47
- // If a thread attempts to issue a log statement when the queue is already maxed out,
48
- // the issuing thread will block until the queue size drops below the max again.
49
-
50
- #define LOG_MAX_QUEUE_SIZE 1000 // Should not exceed INT32_MAX
51
-
52
- // The "global logging queue" refers to [DDLog loggingQueue].
53
- // It is the queue that all log statements go through.
54
- //
55
- // The logging queue sets a flag via dispatch_queue_set_specific using this key.
56
- // We can check for this key via dispatch_get_specific() to see if we're on the "global logging queue".
57
-
58
- static void *const GlobalLoggingQueueIdentityKey = (void *)&GlobalLoggingQueueIdentityKey;
59
-
60
-
61
- @interface DDLoggerNode : NSObject {
62
- @public
63
- id <DDLogger> logger;
64
- dispatch_queue_t loggerQueue;
65
- int logLevel;
66
- }
67
-
68
- @property (nonatomic, assign, readonly) int logLevel;
69
-
70
- + (DDLoggerNode *)nodeWithLogger:(id <DDLogger>)logger loggerQueue:(dispatch_queue_t)loggerQueue logLevel:(int)logLevel;
71
-
72
- @end
73
-
74
-
75
- @interface DDLog (PrivateAPI)
76
-
77
- + (void)lt_addLogger:(id <DDLogger>)logger logLevel:(int)logLevel;
78
- + (void)lt_removeLogger:(id <DDLogger>)logger;
79
- + (void)lt_removeAllLoggers;
80
- + (NSArray *)lt_allLoggers;
81
- + (void)lt_log:(DDLogMessage *)logMessage;
82
- + (void)lt_flush;
83
-
84
- @end
85
-
86
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
87
- #pragma mark -
88
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
89
-
90
- @implementation DDLog
91
-
92
- // An array used to manage all the individual loggers.
93
- // The array is only modified on the loggingQueue/loggingThread.
94
- static NSMutableArray *loggers;
95
-
96
- // All logging statements are added to the same queue to ensure FIFO operation.
97
- static dispatch_queue_t loggingQueue;
98
-
99
- // Individual loggers are executed concurrently per log statement.
100
- // Each logger has it's own associated queue, and a dispatch group is used for synchrnoization.
101
- static dispatch_group_t loggingGroup;
102
-
103
- // In order to prevent to queue from growing infinitely large,
104
- // a maximum size is enforced (LOG_MAX_QUEUE_SIZE).
105
- static dispatch_semaphore_t queueSemaphore;
106
-
107
- // Minor optimization for uniprocessor machines
108
- static unsigned int numProcessors;
109
-
110
- /**
111
- * The runtime sends initialize to each class in a program exactly one time just before the class,
112
- * or any class that inherits from it, is sent its first message from within the program. (Thus the
113
- * method may never be invoked if the class is not used.) The runtime sends the initialize message to
114
- * classes in a thread-safe manner. Superclasses receive this message before their subclasses.
115
- *
116
- * This method may also be called directly (assumably by accident), hence the safety mechanism.
117
- **/
118
- + (void)initialize
119
- {
120
- static BOOL initialized = NO;
121
- if (!initialized)
122
- {
123
- initialized = YES;
124
-
125
- loggers = [[NSMutableArray alloc] initWithCapacity:4];
126
-
127
- NSLogDebug(@"DDLog: Using grand central dispatch");
128
-
129
- loggingQueue = dispatch_queue_create("cocoa.lumberjack", NULL);
130
- loggingGroup = dispatch_group_create();
131
-
132
- void *nonNullValue = GlobalLoggingQueueIdentityKey; // Whatever, just not null
133
- dispatch_queue_set_specific(loggingQueue, GlobalLoggingQueueIdentityKey, nonNullValue, NULL);
134
-
135
- queueSemaphore = dispatch_semaphore_create(LOG_MAX_QUEUE_SIZE);
136
-
137
- // Figure out how many processors are available.
138
- // This may be used later for an optimization on uniprocessor machines.
139
-
140
- host_basic_info_data_t hostInfo;
141
- mach_msg_type_number_t infoCount;
142
-
143
- infoCount = HOST_BASIC_INFO_COUNT;
144
- host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, &infoCount);
145
-
146
- unsigned int result = (unsigned int)(hostInfo.max_cpus);
147
- unsigned int one = (unsigned int)(1);
148
-
149
- numProcessors = MAX(result, one);
150
-
151
- NSLogDebug(@"DDLog: numProcessors = %u", numProcessors);
152
-
153
-
154
- #if TARGET_OS_IPHONE
155
- NSString *notificationName = @"UIApplicationWillTerminateNotification";
156
- #else
157
- NSString *notificationName = nil;
158
-
159
- if (NSClassFromString(@"NSApplication"))
160
- {
161
- notificationName = @"NSApplicationWillTerminateNotification";
162
- }
163
- else
164
- {
165
- // If there is no NSApp -> we are running Command Line Tool app.
166
- // In this case terminate notification wouldn't be fired, so we use workaround.
167
- atexit_b(^{
168
- [self applicationWillTerminate:nil];
169
- });
170
- }
171
- #endif
172
-
173
- if (notificationName) {
174
- [[NSNotificationCenter defaultCenter] addObserver:self
175
- selector:@selector(applicationWillTerminate:)
176
- name:notificationName
177
- object:nil];
178
- }
179
- }
180
- }
181
-
182
- /**
183
- * Provides access to the logging queue.
184
- **/
185
- + (dispatch_queue_t)loggingQueue
186
- {
187
- return loggingQueue;
188
- }
189
-
190
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
191
- #pragma mark Notifications
192
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
193
-
194
- + (void)applicationWillTerminate:(NSNotification *)notification
195
- {
196
- [self flushLog];
197
- }
198
-
199
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
200
- #pragma mark Logger Management
201
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
202
-
203
- + (void)addLogger:(id <DDLogger>)logger
204
- {
205
- [self addLogger:logger withLogLevel:LOG_LEVEL_VERBOSE];
206
- }
207
-
208
- + (void)addLogger:(id <DDLogger>)logger withLogLevel:(int)logLevel
209
- {
210
- if (logger == nil) return;
211
-
212
- dispatch_async(loggingQueue, ^{ @autoreleasepool {
213
-
214
- [self lt_addLogger:logger logLevel:logLevel];
215
- }});
216
- }
217
-
218
- + (void)removeLogger:(id <DDLogger>)logger
219
- {
220
- if (logger == nil) return;
221
-
222
- dispatch_async(loggingQueue, ^{ @autoreleasepool {
223
-
224
- [self lt_removeLogger:logger];
225
- }});
226
- }
227
-
228
- + (void)removeAllLoggers
229
- {
230
- dispatch_async(loggingQueue, ^{ @autoreleasepool {
231
-
232
- [self lt_removeAllLoggers];
233
- }});
234
- }
235
-
236
- + (NSArray *)allLoggers
237
- {
238
- __block NSArray *theLoggers;
239
-
240
- dispatch_sync(loggingQueue, ^{ @autoreleasepool {
241
- theLoggers = [self lt_allLoggers];
242
- }});
243
-
244
- return theLoggers;
245
- }
246
-
247
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
248
- #pragma mark Master Logging
249
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
250
-
251
- + (void)queueLogMessage:(DDLogMessage *)logMessage asynchronously:(BOOL)asyncFlag
252
- {
253
- // We have a tricky situation here...
254
- //
255
- // In the common case, when the queueSize is below the maximumQueueSize,
256
- // we want to simply enqueue the logMessage. And we want to do this as fast as possible,
257
- // which means we don't want to block and we don't want to use any locks.
258
- //
259
- // However, if the queueSize gets too big, we want to block.
260
- // But we have very strict requirements as to when we block, and how long we block.
261
- //
262
- // The following example should help illustrate our requirements:
263
- //
264
- // Imagine that the maximum queue size is configured to be 5,
265
- // and that there are already 5 log messages queued.
266
- // Let us call these 5 queued log messages A, B, C, D, and E. (A is next to be executed)
267
- //
268
- // Now if our thread issues a log statement (let us call the log message F),
269
- // it should block before the message is added to the queue.
270
- // Furthermore, it should be unblocked immediately after A has been unqueued.
271
- //
272
- // The requirements are strict in this manner so that we block only as long as necessary,
273
- // and so that blocked threads are unblocked in the order in which they were blocked.
274
- //
275
- // Returning to our previous example, let us assume that log messages A through E are still queued.
276
- // Our aforementioned thread is blocked attempting to queue log message F.
277
- // Now assume we have another separate thread that attempts to issue log message G.
278
- // It should block until log messages A and B have been unqueued.
279
-
280
-
281
- // We are using a counting semaphore provided by GCD.
282
- // The semaphore is initialized with our LOG_MAX_QUEUE_SIZE value.
283
- // Everytime we want to queue a log message we decrement this value.
284
- // If the resulting value is less than zero,
285
- // the semaphore function waits in FIFO order for a signal to occur before returning.
286
- //
287
- // A dispatch semaphore is an efficient implementation of a traditional counting semaphore.
288
- // Dispatch semaphores call down to the kernel only when the calling thread needs to be blocked.
289
- // If the calling semaphore does not need to block, no kernel call is made.
290
-
291
- dispatch_semaphore_wait(queueSemaphore, DISPATCH_TIME_FOREVER);
292
-
293
- // We've now sure we won't overflow the queue.
294
- // It is time to queue our log message.
295
-
296
- dispatch_block_t logBlock = ^{ @autoreleasepool {
297
-
298
- [self lt_log:logMessage];
299
- }};
300
-
301
- if (asyncFlag)
302
- dispatch_async(loggingQueue, logBlock);
303
- else
304
- dispatch_sync(loggingQueue, logBlock);
305
- }
306
-
307
- + (void)log:(BOOL)asynchronous
308
- level:(int)level
309
- flag:(int)flag
310
- context:(int)context
311
- file:(const char *)file
312
- function:(const char *)function
313
- line:(int)line
314
- tag:(id)tag
315
- format:(NSString *)format, ...
316
- {
317
- va_list args;
318
- if (format)
319
- {
320
- va_start(args, format);
321
-
322
- NSString *logMsg = [[NSString alloc] initWithFormat:format arguments:args];
323
- DDLogMessage *logMessage = [[DDLogMessage alloc] initWithLogMsg:logMsg
324
- level:level
325
- flag:flag
326
- context:context
327
- file:file
328
- function:function
329
- line:line
330
- tag:tag
331
- options:0];
332
-
333
- [self queueLogMessage:logMessage asynchronously:asynchronous];
334
-
335
- va_end(args);
336
- }
337
- }
338
-
339
- + (void)log:(BOOL)asynchronous
340
- level:(int)level
341
- flag:(int)flag
342
- context:(int)context
343
- file:(const char *)file
344
- function:(const char *)function
345
- line:(int)line
346
- tag:(id)tag
347
- format:(NSString *)format
348
- args:(va_list)args
349
- {
350
- if (format)
351
- {
352
- NSString *logMsg = [[NSString alloc] initWithFormat:format arguments:args];
353
- DDLogMessage *logMessage = [[DDLogMessage alloc] initWithLogMsg:logMsg
354
- level:level
355
- flag:flag
356
- context:context
357
- file:file
358
- function:function
359
- line:line
360
- tag:tag
361
- options:0];
362
-
363
- [self queueLogMessage:logMessage asynchronously:asynchronous];
364
- }
365
- }
366
-
367
- + (void)flushLog
368
- {
369
- dispatch_sync(loggingQueue, ^{ @autoreleasepool {
370
-
371
- [self lt_flush];
372
- }});
373
- }
374
-
375
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
376
- #pragma mark Registered Dynamic Logging
377
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
378
-
379
- + (BOOL)isRegisteredClass:(Class)class
380
- {
381
- SEL getterSel = @selector(ddLogLevel);
382
- SEL setterSel = @selector(ddSetLogLevel:);
383
-
384
- #if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
385
-
386
- // Issue #6 (GoogleCode) - Crashes on iOS 4.2.1 and iPhone 4
387
- //
388
- // Crash caused by class_getClassMethod(2).
389
- //
390
- // "It's a bug with UIAccessibilitySafeCategory__NSObject so it didn't pop up until
391
- // users had VoiceOver enabled [...]. I was able to work around it by searching the
392
- // result of class_copyMethodList() instead of calling class_getClassMethod()"
393
-
394
- BOOL result = NO;
395
-
396
- unsigned int methodCount, i;
397
- Method *methodList = class_copyMethodList(object_getClass(class), &methodCount);
398
-
399
- if (methodList != NULL)
400
- {
401
- BOOL getterFound = NO;
402
- BOOL setterFound = NO;
403
-
404
- for (i = 0; i < methodCount; ++i)
405
- {
406
- SEL currentSel = method_getName(methodList[i]);
407
-
408
- if (currentSel == getterSel)
409
- {
410
- getterFound = YES;
411
- }
412
- else if (currentSel == setterSel)
413
- {
414
- setterFound = YES;
415
- }
416
-
417
- if (getterFound && setterFound)
418
- {
419
- result = YES;
420
- break;
421
- }
422
- }
423
-
424
- free(methodList);
425
- }
426
-
427
- return result;
428
-
429
- #else
430
-
431
- // Issue #24 (GitHub) - Crashing in in ARC+Simulator
432
- //
433
- // The method +[DDLog isRegisteredClass] will crash a project when using it with ARC + Simulator.
434
- // For running in the Simulator, it needs to execute the non-iOS code.
435
-
436
- Method getter = class_getClassMethod(class, getterSel);
437
- Method setter = class_getClassMethod(class, setterSel);
438
-
439
- if ((getter != NULL) && (setter != NULL))
440
- {
441
- return YES;
442
- }
443
-
444
- return NO;
445
-
446
- #endif
447
- }
448
-
449
- + (NSArray *)registeredClasses
450
- {
451
- int numClasses, i;
452
-
453
- // We're going to get the list of all registered classes.
454
- // The Objective-C runtime library automatically registers all the classes defined in your source code.
455
- //
456
- // To do this we use the following method (documented in the Objective-C Runtime Reference):
457
- //
458
- // int objc_getClassList(Class *buffer, int bufferLen)
459
- //
460
- // We can pass (NULL, 0) to obtain the total number of
461
- // registered class definitions without actually retrieving any class definitions.
462
- // This allows us to allocate the minimum amount of memory needed for the application.
463
-
464
- numClasses = objc_getClassList(NULL, 0);
465
-
466
- // The numClasses method now tells us how many classes we have.
467
- // So we can allocate our buffer, and get pointers to all the class definitions.
468
-
469
- Class *classes = (Class *)malloc(sizeof(Class) * numClasses);
470
- if (classes == NULL) return nil;
471
-
472
- numClasses = objc_getClassList(classes, numClasses);
473
-
474
- // We can now loop through the classes, and test each one to see if it is a DDLogging class.
475
-
476
- NSMutableArray *result = [NSMutableArray arrayWithCapacity:numClasses];
477
-
478
- for (i = 0; i < numClasses; i++)
479
- {
480
- Class class = classes[i];
481
-
482
- if ([self isRegisteredClass:class])
483
- {
484
- [result addObject:class];
485
- }
486
- }
487
-
488
- free(classes);
489
-
490
- return result;
491
- }
492
-
493
- + (NSArray *)registeredClassNames
494
- {
495
- NSArray *registeredClasses = [self registeredClasses];
496
- NSMutableArray *result = [NSMutableArray arrayWithCapacity:[registeredClasses count]];
497
-
498
- for (Class class in registeredClasses)
499
- {
500
- [result addObject:NSStringFromClass(class)];
501
- }
502
-
503
- return result;
504
- }
505
-
506
- + (int)logLevelForClass:(Class)aClass
507
- {
508
- if ([self isRegisteredClass:aClass])
509
- {
510
- return [aClass ddLogLevel];
511
- }
512
-
513
- return -1;
514
- }
515
-
516
- + (int)logLevelForClassWithName:(NSString *)aClassName
517
- {
518
- Class aClass = NSClassFromString(aClassName);
519
-
520
- return [self logLevelForClass:aClass];
521
- }
522
-
523
- + (void)setLogLevel:(int)logLevel forClass:(Class)aClass
524
- {
525
- if ([self isRegisteredClass:aClass])
526
- {
527
- [aClass ddSetLogLevel:logLevel];
528
- }
529
- }
530
-
531
- + (void)setLogLevel:(int)logLevel forClassWithName:(NSString *)aClassName
532
- {
533
- Class aClass = NSClassFromString(aClassName);
534
-
535
- [self setLogLevel:logLevel forClass:aClass];
536
- }
537
-
538
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
539
- #pragma mark Logging Thread
540
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
541
-
542
- + (void)lt_addLogger:(id <DDLogger>)logger logLevel:(int)logLevel
543
- {
544
- // Add to loggers array.
545
- // Need to create loggerQueue if loggerNode doesn't provide one.
546
-
547
- NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
548
- @"This method should only be run on the logging thread/queue");
549
-
550
- dispatch_queue_t loggerQueue = NULL;
551
-
552
- if ([logger respondsToSelector:@selector(loggerQueue)])
553
- {
554
- // Logger may be providing its own queue
555
-
556
- loggerQueue = [logger loggerQueue];
557
- }
558
-
559
- if (loggerQueue == nil)
560
- {
561
- // Automatically create queue for the logger.
562
- // Use the logger name as the queue name if possible.
563
-
564
- const char *loggerQueueName = NULL;
565
- if ([logger respondsToSelector:@selector(loggerName)])
566
- {
567
- loggerQueueName = [[logger loggerName] UTF8String];
568
- }
569
-
570
- loggerQueue = dispatch_queue_create(loggerQueueName, NULL);
571
- }
572
-
573
- DDLoggerNode *loggerNode = [DDLoggerNode nodeWithLogger:logger loggerQueue:loggerQueue logLevel:logLevel];
574
- [loggers addObject:loggerNode];
575
-
576
- if ([logger respondsToSelector:@selector(didAddLogger)])
577
- {
578
- dispatch_async(loggerNode->loggerQueue, ^{ @autoreleasepool {
579
-
580
- [logger didAddLogger];
581
- }});
582
- }
583
- }
584
-
585
- + (void)lt_removeLogger:(id <DDLogger>)logger
586
- {
587
- // Find associated loggerNode in list of added loggers
588
-
589
- NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
590
- @"This method should only be run on the logging thread/queue");
591
-
592
- DDLoggerNode *loggerNode = nil;
593
-
594
- for (DDLoggerNode *node in loggers)
595
- {
596
- if (node->logger == logger)
597
- {
598
- loggerNode = node;
599
- break;
600
- }
601
- }
602
-
603
- if (loggerNode == nil)
604
- {
605
- NSLogDebug(@"DDLog: Request to remove logger which wasn't added");
606
- return;
607
- }
608
-
609
- // Notify logger
610
-
611
- if ([logger respondsToSelector:@selector(willRemoveLogger)])
612
- {
613
- dispatch_async(loggerNode->loggerQueue, ^{ @autoreleasepool {
614
-
615
- [logger willRemoveLogger];
616
- }});
617
- }
618
-
619
- // Remove from loggers array
620
-
621
- [loggers removeObject:loggerNode];
622
- }
623
-
624
- + (void)lt_removeAllLoggers
625
- {
626
- // Notify all loggers
627
-
628
- NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
629
- @"This method should only be run on the logging thread/queue");
630
-
631
- for (DDLoggerNode *loggerNode in loggers)
632
- {
633
- if ([loggerNode->logger respondsToSelector:@selector(willRemoveLogger)])
634
- {
635
- dispatch_async(loggerNode->loggerQueue, ^{ @autoreleasepool {
636
-
637
- [loggerNode->logger willRemoveLogger];
638
- }});
639
- }
640
- }
641
-
642
- // Remove all loggers from array
643
-
644
- [loggers removeAllObjects];
645
- }
646
-
647
- + (NSArray *)lt_allLoggers
648
- {
649
- NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
650
- @"This method should only be run on the logging thread/queue");
651
-
652
- NSMutableArray *theLoggers = [NSMutableArray new];
653
-
654
- for (DDLoggerNode *loggerNode in loggers)
655
- {
656
- [theLoggers addObject:loggerNode->logger];
657
- }
658
-
659
- return [theLoggers copy];
660
- }
661
-
662
- + (void)lt_log:(DDLogMessage *)logMessage
663
- {
664
- // Execute the given log message on each of our loggers.
665
-
666
- NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
667
- @"This method should only be run on the logging thread/queue");
668
-
669
- if (numProcessors > 1)
670
- {
671
- // Execute each logger concurrently, each within its own queue.
672
- // All blocks are added to same group.
673
- // After each block has been queued, wait on group.
674
- //
675
- // The waiting ensures that a slow logger doesn't end up with a large queue of pending log messages.
676
- // This would defeat the purpose of the efforts we made earlier to restrict the max queue size.
677
-
678
- for (DDLoggerNode *loggerNode in loggers)
679
- {
680
- // skip the loggers that shouldn't write this message based on the logLevel
681
-
682
- if (!(logMessage->logFlag & loggerNode.logLevel))
683
- continue;
684
-
685
- dispatch_group_async(loggingGroup, loggerNode->loggerQueue, ^{ @autoreleasepool {
686
-
687
- [loggerNode->logger logMessage:logMessage];
688
-
689
- }});
690
- }
691
-
692
- dispatch_group_wait(loggingGroup, DISPATCH_TIME_FOREVER);
693
- }
694
- else
695
- {
696
- // Execute each logger serialy, each within its own queue.
697
-
698
- for (DDLoggerNode *loggerNode in loggers)
699
- {
700
- // skip the loggers that shouldn't write this message based on the logLevel
701
-
702
- if (!(logMessage->logFlag & loggerNode.logLevel))
703
- continue;
704
-
705
- dispatch_sync(loggerNode->loggerQueue, ^{ @autoreleasepool {
706
-
707
- [loggerNode->logger logMessage:logMessage];
708
-
709
- }});
710
- }
711
- }
712
-
713
- // If our queue got too big, there may be blocked threads waiting to add log messages to the queue.
714
- // Since we've now dequeued an item from the log, we may need to unblock the next thread.
715
-
716
- // We are using a counting semaphore provided by GCD.
717
- // The semaphore is initialized with our LOG_MAX_QUEUE_SIZE value.
718
- // When a log message is queued this value is decremented.
719
- // When a log message is dequeued this value is incremented.
720
- // If the value ever drops below zero,
721
- // the queueing thread blocks and waits in FIFO order for us to signal it.
722
- //
723
- // A dispatch semaphore is an efficient implementation of a traditional counting semaphore.
724
- // Dispatch semaphores call down to the kernel only when the calling thread needs to be blocked.
725
- // If the calling semaphore does not need to block, no kernel call is made.
726
-
727
- dispatch_semaphore_signal(queueSemaphore);
728
- }
729
-
730
- + (void)lt_flush
731
- {
732
- // All log statements issued before the flush method was invoked have now been executed.
733
- //
734
- // Now we need to propogate the flush request to any loggers that implement the flush method.
735
- // This is designed for loggers that buffer IO.
736
-
737
- NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
738
- @"This method should only be run on the logging thread/queue");
739
-
740
- for (DDLoggerNode *loggerNode in loggers)
741
- {
742
- if ([loggerNode->logger respondsToSelector:@selector(flush)])
743
- {
744
- dispatch_group_async(loggingGroup, loggerNode->loggerQueue, ^{ @autoreleasepool {
745
-
746
- [loggerNode->logger flush];
747
-
748
- }});
749
- }
750
- }
751
-
752
- dispatch_group_wait(loggingGroup, DISPATCH_TIME_FOREVER);
753
- }
754
-
755
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
756
- #pragma mark Utilities
757
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
758
-
759
- NSString *DDExtractFileNameWithoutExtension(const char *filePath, BOOL copy)
760
- {
761
- if (filePath == NULL) return nil;
762
-
763
- char *lastSlash = NULL;
764
- char *lastDot = NULL;
765
-
766
- char *p = (char *)filePath;
767
-
768
- while (*p != '\0')
769
- {
770
- if (*p == '/')
771
- lastSlash = p;
772
- else if (*p == '.')
773
- lastDot = p;
774
-
775
- p++;
776
- }
777
-
778
- char *subStr;
779
- NSUInteger subLen;
780
-
781
- if (lastSlash)
782
- {
783
- if (lastDot)
784
- {
785
- // lastSlash -> lastDot
786
- subStr = lastSlash + 1;
787
- subLen = lastDot - subStr;
788
- }
789
- else
790
- {
791
- // lastSlash -> endOfString
792
- subStr = lastSlash + 1;
793
- subLen = p - subStr;
794
- }
795
- }
796
- else
797
- {
798
- if (lastDot)
799
- {
800
- // startOfString -> lastDot
801
- subStr = (char *)filePath;
802
- subLen = lastDot - subStr;
803
- }
804
- else
805
- {
806
- // startOfString -> endOfString
807
- subStr = (char *)filePath;
808
- subLen = p - subStr;
809
- }
810
- }
811
-
812
- if (copy)
813
- {
814
- return [[NSString alloc] initWithBytes:subStr
815
- length:subLen
816
- encoding:NSUTF8StringEncoding];
817
- }
818
- else
819
- {
820
- // We can take advantage of the fact that __FILE__ is a string literal.
821
- // Specifically, we don't need to waste time copying the string.
822
- // We can just tell NSString to point to a range within the string literal.
823
-
824
- return [[NSString alloc] initWithBytesNoCopy:subStr
825
- length:subLen
826
- encoding:NSUTF8StringEncoding
827
- freeWhenDone:NO];
828
- }
829
- }
830
-
831
- @end
832
-
833
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
834
- #pragma mark -
835
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
836
-
837
- @implementation DDLoggerNode
838
-
839
- @synthesize logLevel;
840
-
841
- - (instancetype)initWithLogger:(id <DDLogger>)aLogger loggerQueue:(dispatch_queue_t)aLoggerQueue logLevel:(int)aLogLevel
842
- {
843
- if ((self = [super init]))
844
- {
845
- logger = aLogger;
846
-
847
- if (aLoggerQueue) {
848
- loggerQueue = aLoggerQueue;
849
- #if !OS_OBJECT_USE_OBJC
850
- dispatch_retain(loggerQueue);
851
- #endif
852
- }
853
- logLevel = aLogLevel;
854
- }
855
- return self;
856
- }
857
-
858
- + (DDLoggerNode *)nodeWithLogger:(id <DDLogger>)logger loggerQueue:(dispatch_queue_t)loggerQueue logLevel:(int)logLevel
859
- {
860
- return [[DDLoggerNode alloc] initWithLogger:logger loggerQueue:loggerQueue logLevel:logLevel];
861
- }
862
-
863
- - (void)dealloc
864
- {
865
- #if !OS_OBJECT_USE_OBJC
866
- if (loggerQueue) dispatch_release(loggerQueue);
867
- #endif
868
- }
869
-
870
- @end
871
-
872
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
873
- #pragma mark -
874
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
875
-
876
- @implementation DDLogMessage
877
-
878
- static char *dd_str_copy(const char *str)
879
- {
880
- if (str == NULL) return NULL;
881
-
882
- size_t length = strlen(str);
883
- char * result = malloc(length + 1);
884
- if (result == NULL) return NULL;
885
- strncpy(result, str, length);
886
- result[length] = 0;
887
-
888
- return result;
889
- }
890
-
891
- - (instancetype)initWithLogMsg:(NSString *)msg
892
- level:(int)level
893
- flag:(int)flag
894
- context:(int)context
895
- file:(const char *)aFile
896
- function:(const char *)aFunction
897
- line:(int)line
898
- tag:(id)aTag
899
- options:(DDLogMessageOptions)optionsMask
900
- {
901
- if ((self = [super init]))
902
- {
903
- logMsg = msg;
904
- logLevel = level;
905
- logFlag = flag;
906
- logContext = context;
907
- lineNumber = line;
908
- tag = aTag;
909
- options = optionsMask;
910
-
911
- if (options & DDLogMessageCopyFile)
912
- file = dd_str_copy(aFile);
913
- else
914
- file = (char *)aFile;
915
-
916
- if (options & DDLogMessageCopyFunction)
917
- function = dd_str_copy(aFunction);
918
- else
919
- function = (char *)aFunction;
920
-
921
- timestamp = [[NSDate alloc] init];
922
-
923
- machThreadID = pthread_mach_thread_np(pthread_self());
924
-
925
- // Try to get the current queue's label
926
-
927
- // a) Compiling against newer SDK's (iOS 7+/OS X 10.9+) where DISPATCH_CURRENT_QUEUE_LABEL is defined
928
- // on a (iOS 7.0+/OS X 10.9+) runtime version
929
- BOOL gotLabel = NO;
930
- #ifdef DISPATCH_CURRENT_QUEUE_LABEL
931
- if (
932
- #if TARGET_OS_IPHONE
933
- #ifndef NSFoundationVersionNumber_iOS_6_1
934
- #define NSFoundationVersionNumber_iOS_6_1 993.00
935
- #endif
936
- floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1 // iOS 7+ (> iOS 6.1)
937
- #else
938
- [NSTimer instancesRespondToSelector:@selector(tolerance)] // OS X 10.9+
939
- #endif
940
- ) {
941
- queueLabel = dd_str_copy(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL));
942
- gotLabel = YES;
943
- }
944
- #endif
945
-
946
- // b) Systems where dispatch_get_current_queue is not yet deprecated and won't crash (< iOS 6.0/OS X 10.9)
947
- // dispatch_get_current_queue(void); __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6,__MAC_10_9,__IPHONE_4_0,__IPHONE_6_0)
948
- if (!gotLabel &&
949
- #if TARGET_OS_IPHONE
950
- #ifndef NSFoundationVersionNumber_iOS_6_0
951
- #define NSFoundationVersionNumber_iOS_6_0 993.00
952
- #endif
953
- floor(NSFoundationVersionNumber) < NSFoundationVersionNumber_iOS_6_0 // < iOS 6.0
954
- #else
955
- ![NSTimer instancesRespondToSelector:@selector(tolerance)] // < OS X 10.9
956
- #endif
957
- ) {
958
- #pragma clang diagnostic push
959
- #pragma clang diagnostic ignored "-Wdeprecated-declarations"
960
- dispatch_queue_t currentQueue = dispatch_get_current_queue();
961
- #pragma clang diagnostic pop
962
-
963
- queueLabel = dd_str_copy(dispatch_queue_get_label(currentQueue));
964
- gotLabel = YES;
965
- }
966
-
967
- // c) Give up
968
- if (!gotLabel) {
969
- queueLabel = dd_str_copy(""); // iOS 6.x only
970
- }
971
-
972
- threadName = [[NSThread currentThread] name];
973
- }
974
- return self;
975
- }
976
-
977
- - (NSString *)threadID
978
- {
979
- return [[NSString alloc] initWithFormat:@"%x", machThreadID];
980
- }
981
-
982
- - (NSString *)fileName
983
- {
984
- return DDExtractFileNameWithoutExtension(file, NO);
985
- }
986
-
987
- - (NSString *)methodName
988
- {
989
- if (function == NULL)
990
- return nil;
991
- else
992
- return [[NSString alloc] initWithUTF8String:function];
993
- }
994
-
995
- - (void)dealloc
996
- {
997
- if (file && (options & DDLogMessageCopyFile))
998
- free(file);
999
-
1000
- if (function && (options & DDLogMessageCopyFunction))
1001
- free(function);
1002
-
1003
- if (queueLabel)
1004
- free(queueLabel);
1005
- }
1006
-
1007
-
1008
- - (id)copyWithZone:(NSZone *)zone {
1009
- DDLogMessage *newMessage = [[DDLogMessage alloc] init];
1010
-
1011
- newMessage->logLevel = self->logLevel;
1012
- newMessage->logFlag = self->logFlag;
1013
- newMessage->logContext = self->logContext;
1014
- newMessage->logMsg = self->logMsg;
1015
- newMessage->timestamp = self->timestamp;
1016
-
1017
- if (self->options & DDLogMessageCopyFile) {
1018
- newMessage->file = dd_str_copy(self->file);
1019
- newMessage->function = dd_str_copy(self->function);
1020
- } else {
1021
- newMessage->file = self->file;
1022
- newMessage->function = self->function;
1023
- }
1024
-
1025
- newMessage->lineNumber = self->lineNumber;
1026
-
1027
- newMessage->machThreadID = self->machThreadID;
1028
- newMessage->queueLabel = dd_str_copy(self->queueLabel);
1029
- newMessage->threadName = self->threadName;
1030
- newMessage->tag = self->tag;
1031
- newMessage->options = self->options;
1032
-
1033
- return newMessage;
1034
- }
1035
-
1036
- @end
1037
-
1038
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1039
- #pragma mark -
1040
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1041
-
1042
- @implementation DDAbstractLogger
1043
-
1044
- - (id)init
1045
- {
1046
- if ((self = [super init]))
1047
- {
1048
- const char *loggerQueueName = NULL;
1049
- if ([self respondsToSelector:@selector(loggerName)])
1050
- {
1051
- loggerQueueName = [[self loggerName] UTF8String];
1052
- }
1053
-
1054
- loggerQueue = dispatch_queue_create(loggerQueueName, NULL);
1055
-
1056
- // We're going to use dispatch_queue_set_specific() to "mark" our loggerQueue.
1057
- // Later we can use dispatch_get_specific() to determine if we're executing on our loggerQueue.
1058
- // The documentation states:
1059
- //
1060
- // > Keys are only compared as pointers and are never dereferenced.
1061
- // > Thus, you can use a pointer to a static variable for a specific subsystem or
1062
- // > any other value that allows you to identify the value uniquely.
1063
- // > Specifying a pointer to a string constant is not recommended.
1064
- //
1065
- // So we're going to use the very convenient key of "self",
1066
- // which also works when multiple logger classes extend this class, as each will have a different "self" key.
1067
- //
1068
- // This is used primarily for thread-safety assertions (via the isOnInternalLoggerQueue method below).
1069
-
1070
- void *key = (__bridge void *)self;
1071
- void *nonNullValue = (__bridge void *)self;
1072
-
1073
- dispatch_queue_set_specific(loggerQueue, key, nonNullValue, NULL);
1074
- }
1075
- return self;
1076
- }
1077
-
1078
- - (void)dealloc
1079
- {
1080
- #if !OS_OBJECT_USE_OBJC
1081
- if (loggerQueue) dispatch_release(loggerQueue);
1082
- #endif
1083
- }
1084
-
1085
- - (void)logMessage:(DDLogMessage *)logMessage
1086
- {
1087
- // Override me
1088
- }
1089
-
1090
- - (id <DDLogFormatter>)logFormatter
1091
- {
1092
- // This method must be thread safe and intuitive.
1093
- // Therefore if somebody executes the following code:
1094
- //
1095
- // [logger setLogFormatter:myFormatter];
1096
- // formatter = [logger logFormatter];
1097
- //
1098
- // They would expect formatter to equal myFormatter.
1099
- // This functionality must be ensured by the getter and setter method.
1100
- //
1101
- // The thread safety must not come at a cost to the performance of the logMessage method.
1102
- // This method is likely called sporadically, while the logMessage method is called repeatedly.
1103
- // This means, the implementation of this method:
1104
- // - Must NOT require the logMessage method to acquire a lock.
1105
- // - Must NOT require the logMessage method to access an atomic property (also a lock of sorts).
1106
- //
1107
- // Thread safety is ensured by executing access to the formatter variable on the loggerQueue.
1108
- // This is the same queue that the logMessage method operates on.
1109
- //
1110
- // Note: The last time I benchmarked the performance of direct access vs atomic property access,
1111
- // direct access was over twice as fast on the desktop and over 6 times as fast on the iPhone.
1112
- //
1113
- // Furthermore, consider the following code:
1114
- //
1115
- // DDLogVerbose(@"log msg 1");
1116
- // DDLogVerbose(@"log msg 2");
1117
- // [logger setFormatter:myFormatter];
1118
- // DDLogVerbose(@"log msg 3");
1119
- //
1120
- // Our intuitive requirement means that the new formatter will only apply to the 3rd log message.
1121
- // This must remain true even when using asynchronous logging.
1122
- // We must keep in mind the various queue's that are in play here:
1123
- //
1124
- // loggerQueue : Our own private internal queue that the logMessage method runs on.
1125
- // Operations are added to this queue from the global loggingQueue.
1126
- //
1127
- // globalLoggingQueue : The queue that all log messages go through before they arrive in our loggerQueue.
1128
- //
1129
- // All log statements go through the serial gloabalLoggingQueue before they arrive at our loggerQueue.
1130
- // Thus this method also goes through the serial globalLoggingQueue to ensure intuitive operation.
1131
-
1132
- // IMPORTANT NOTE:
1133
- //
1134
- // Methods within the DDLogger implementation MUST access the formatter ivar directly.
1135
- // This method is designed explicitly for external access.
1136
- //
1137
- // Using "self." syntax to go through this method will cause immediate deadlock.
1138
- // This is the intended result. Fix it by accessing the ivar directly.
1139
- // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
1140
-
1141
- NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
1142
- NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
1143
-
1144
- dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
1145
-
1146
- __block id <DDLogFormatter> result;
1147
-
1148
- dispatch_sync(globalLoggingQueue, ^{
1149
- dispatch_sync(loggerQueue, ^{
1150
- result = formatter;
1151
- });
1152
- });
1153
-
1154
- return result;
1155
- }
1156
-
1157
- - (void)setLogFormatter:(id <DDLogFormatter>)logFormatter
1158
- {
1159
- // The design of this method is documented extensively in the logFormatter message (above in code).
1160
-
1161
- NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
1162
- NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
1163
-
1164
- dispatch_block_t block = ^{ @autoreleasepool {
1165
-
1166
- if (formatter != logFormatter)
1167
- {
1168
- if ([formatter respondsToSelector:@selector(willRemoveFromLogger:)]) {
1169
- [formatter willRemoveFromLogger:self];
1170
- }
1171
-
1172
- formatter = logFormatter;
1173
-
1174
- if ([formatter respondsToSelector:@selector(didAddToLogger:)]) {
1175
- [formatter didAddToLogger:self];
1176
- }
1177
- }
1178
- }};
1179
-
1180
- dispatch_queue_t globalLoggingQueue = [DDLog loggingQueue];
1181
-
1182
- dispatch_async(globalLoggingQueue, ^{
1183
- dispatch_async(loggerQueue, block);
1184
- });
1185
- }
1186
-
1187
- - (dispatch_queue_t)loggerQueue
1188
- {
1189
- return loggerQueue;
1190
- }
1191
-
1192
- - (NSString *)loggerName
1193
- {
1194
- return NSStringFromClass([self class]);
1195
- }
1196
-
1197
- - (BOOL)isOnGlobalLoggingQueue
1198
- {
1199
- return (dispatch_get_specific(GlobalLoggingQueueIdentityKey) != NULL);
1200
- }
1201
-
1202
- - (BOOL)isOnInternalLoggerQueue
1203
- {
1204
- void *key = (__bridge void *)self;
1205
- return (dispatch_get_specific(key) != NULL);
1206
- }
1207
-
1208
- @end