├── .gitignore ├── BMTimeCalculateDemo ├── BMTimeCalculateDemo.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── BMTimeCalculateDemo │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── BMTimeCalculate │ │ ├── BMTimeCalculate.h │ │ └── BMTimeCalculate.m │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── ViewController.h │ ├── ViewController.m │ └── main.m ├── BMTimeCalculateDemoTests │ ├── BMTimeCalculateDemoTests.m │ └── Info.plist └── BMTimeCalculateDemoUITests │ ├── BMTimeCalculateDemoUITests.m │ └── Info.plist ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata 19 | 20 | ## Other 21 | *.xccheckout 22 | *.moved-aside 23 | *.xcuserstate 24 | *.xcscmblueprint 25 | 26 | ## Obj-C/Swift specific 27 | *.hmap 28 | *.ipa 29 | 30 | # CocoaPods 31 | # 32 | # We recommend against adding the Pods directory to your .gitignore. However 33 | # you should judge for yourself, the pros and cons are mentioned at: 34 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 35 | # 36 | # Pods/ 37 | 38 | # Carthage 39 | # 40 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 41 | # Carthage/Checkouts 42 | 43 | Carthage/Build 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md 51 | 52 | fastlane/report.xml 53 | fastlane/screenshots 54 | -------------------------------------------------------------------------------- /BMTimeCalculateDemo/BMTimeCalculateDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2EAD68DD1CDDDF2B0086F0C3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2EAD68DC1CDDDF2B0086F0C3 /* main.m */; }; 11 | 2EAD68E01CDDDF2B0086F0C3 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2EAD68DF1CDDDF2B0086F0C3 /* AppDelegate.m */; }; 12 | 2EAD68E31CDDDF2B0086F0C3 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2EAD68E21CDDDF2B0086F0C3 /* ViewController.m */; }; 13 | 2EAD68E61CDDDF2B0086F0C3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2EAD68E41CDDDF2B0086F0C3 /* Main.storyboard */; }; 14 | 2EAD68E81CDDDF2B0086F0C3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2EAD68E71CDDDF2B0086F0C3 /* Assets.xcassets */; }; 15 | 2EAD68EB1CDDDF2B0086F0C3 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2EAD68E91CDDDF2B0086F0C3 /* LaunchScreen.storyboard */; }; 16 | 2EAD68F61CDDDF2B0086F0C3 /* BMTimeCalculateDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2EAD68F51CDDDF2B0086F0C3 /* BMTimeCalculateDemoTests.m */; }; 17 | 2EAD69011CDDDF2B0086F0C3 /* BMTimeCalculateDemoUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2EAD69001CDDDF2B0086F0C3 /* BMTimeCalculateDemoUITests.m */; }; 18 | 2EAD69111CDDDF770086F0C3 /* BMTimeCalculate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2EAD69101CDDDF770086F0C3 /* BMTimeCalculate.m */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXContainerItemProxy section */ 22 | 2EAD68F21CDDDF2B0086F0C3 /* PBXContainerItemProxy */ = { 23 | isa = PBXContainerItemProxy; 24 | containerPortal = 2EAD68D01CDDDF2B0086F0C3 /* Project object */; 25 | proxyType = 1; 26 | remoteGlobalIDString = 2EAD68D71CDDDF2B0086F0C3; 27 | remoteInfo = BMTimeCalculateDemo; 28 | }; 29 | 2EAD68FD1CDDDF2B0086F0C3 /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = 2EAD68D01CDDDF2B0086F0C3 /* Project object */; 32 | proxyType = 1; 33 | remoteGlobalIDString = 2EAD68D71CDDDF2B0086F0C3; 34 | remoteInfo = BMTimeCalculateDemo; 35 | }; 36 | /* End PBXContainerItemProxy section */ 37 | 38 | /* Begin PBXFileReference section */ 39 | 2EAD68D81CDDDF2B0086F0C3 /* BMTimeCalculateDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BMTimeCalculateDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 40 | 2EAD68DC1CDDDF2B0086F0C3 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 41 | 2EAD68DE1CDDDF2B0086F0C3 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 42 | 2EAD68DF1CDDDF2B0086F0C3 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 43 | 2EAD68E11CDDDF2B0086F0C3 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 44 | 2EAD68E21CDDDF2B0086F0C3 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 45 | 2EAD68E51CDDDF2B0086F0C3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 46 | 2EAD68E71CDDDF2B0086F0C3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 47 | 2EAD68EA1CDDDF2B0086F0C3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 48 | 2EAD68EC1CDDDF2B0086F0C3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 49 | 2EAD68F11CDDDF2B0086F0C3 /* BMTimeCalculateDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BMTimeCalculateDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | 2EAD68F51CDDDF2B0086F0C3 /* BMTimeCalculateDemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BMTimeCalculateDemoTests.m; sourceTree = ""; }; 51 | 2EAD68F71CDDDF2B0086F0C3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 52 | 2EAD68FC1CDDDF2B0086F0C3 /* BMTimeCalculateDemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BMTimeCalculateDemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 2EAD69001CDDDF2B0086F0C3 /* BMTimeCalculateDemoUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BMTimeCalculateDemoUITests.m; sourceTree = ""; }; 54 | 2EAD69021CDDDF2B0086F0C3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 55 | 2EAD690F1CDDDF770086F0C3 /* BMTimeCalculate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BMTimeCalculate.h; sourceTree = ""; }; 56 | 2EAD69101CDDDF770086F0C3 /* BMTimeCalculate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BMTimeCalculate.m; sourceTree = ""; }; 57 | /* End PBXFileReference section */ 58 | 59 | /* Begin PBXFrameworksBuildPhase section */ 60 | 2EAD68D51CDDDF2B0086F0C3 /* Frameworks */ = { 61 | isa = PBXFrameworksBuildPhase; 62 | buildActionMask = 2147483647; 63 | files = ( 64 | ); 65 | runOnlyForDeploymentPostprocessing = 0; 66 | }; 67 | 2EAD68EE1CDDDF2B0086F0C3 /* Frameworks */ = { 68 | isa = PBXFrameworksBuildPhase; 69 | buildActionMask = 2147483647; 70 | files = ( 71 | ); 72 | runOnlyForDeploymentPostprocessing = 0; 73 | }; 74 | 2EAD68F91CDDDF2B0086F0C3 /* Frameworks */ = { 75 | isa = PBXFrameworksBuildPhase; 76 | buildActionMask = 2147483647; 77 | files = ( 78 | ); 79 | runOnlyForDeploymentPostprocessing = 0; 80 | }; 81 | /* End PBXFrameworksBuildPhase section */ 82 | 83 | /* Begin PBXGroup section */ 84 | 2EAD68CF1CDDDF2B0086F0C3 = { 85 | isa = PBXGroup; 86 | children = ( 87 | 2EAD68DA1CDDDF2B0086F0C3 /* BMTimeCalculateDemo */, 88 | 2EAD68F41CDDDF2B0086F0C3 /* BMTimeCalculateDemoTests */, 89 | 2EAD68FF1CDDDF2B0086F0C3 /* BMTimeCalculateDemoUITests */, 90 | 2EAD68D91CDDDF2B0086F0C3 /* Products */, 91 | ); 92 | sourceTree = ""; 93 | }; 94 | 2EAD68D91CDDDF2B0086F0C3 /* Products */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | 2EAD68D81CDDDF2B0086F0C3 /* BMTimeCalculateDemo.app */, 98 | 2EAD68F11CDDDF2B0086F0C3 /* BMTimeCalculateDemoTests.xctest */, 99 | 2EAD68FC1CDDDF2B0086F0C3 /* BMTimeCalculateDemoUITests.xctest */, 100 | ); 101 | name = Products; 102 | sourceTree = ""; 103 | }; 104 | 2EAD68DA1CDDDF2B0086F0C3 /* BMTimeCalculateDemo */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 2EAD690E1CDDDF770086F0C3 /* BMTimeCalculate */, 108 | 2EAD68DE1CDDDF2B0086F0C3 /* AppDelegate.h */, 109 | 2EAD68DF1CDDDF2B0086F0C3 /* AppDelegate.m */, 110 | 2EAD68E11CDDDF2B0086F0C3 /* ViewController.h */, 111 | 2EAD68E21CDDDF2B0086F0C3 /* ViewController.m */, 112 | 2EAD68E41CDDDF2B0086F0C3 /* Main.storyboard */, 113 | 2EAD68E71CDDDF2B0086F0C3 /* Assets.xcassets */, 114 | 2EAD68E91CDDDF2B0086F0C3 /* LaunchScreen.storyboard */, 115 | 2EAD68EC1CDDDF2B0086F0C3 /* Info.plist */, 116 | 2EAD68DB1CDDDF2B0086F0C3 /* Supporting Files */, 117 | ); 118 | path = BMTimeCalculateDemo; 119 | sourceTree = ""; 120 | }; 121 | 2EAD68DB1CDDDF2B0086F0C3 /* Supporting Files */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | 2EAD68DC1CDDDF2B0086F0C3 /* main.m */, 125 | ); 126 | name = "Supporting Files"; 127 | sourceTree = ""; 128 | }; 129 | 2EAD68F41CDDDF2B0086F0C3 /* BMTimeCalculateDemoTests */ = { 130 | isa = PBXGroup; 131 | children = ( 132 | 2EAD68F51CDDDF2B0086F0C3 /* BMTimeCalculateDemoTests.m */, 133 | 2EAD68F71CDDDF2B0086F0C3 /* Info.plist */, 134 | ); 135 | path = BMTimeCalculateDemoTests; 136 | sourceTree = ""; 137 | }; 138 | 2EAD68FF1CDDDF2B0086F0C3 /* BMTimeCalculateDemoUITests */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | 2EAD69001CDDDF2B0086F0C3 /* BMTimeCalculateDemoUITests.m */, 142 | 2EAD69021CDDDF2B0086F0C3 /* Info.plist */, 143 | ); 144 | path = BMTimeCalculateDemoUITests; 145 | sourceTree = ""; 146 | }; 147 | 2EAD690E1CDDDF770086F0C3 /* BMTimeCalculate */ = { 148 | isa = PBXGroup; 149 | children = ( 150 | 2EAD690F1CDDDF770086F0C3 /* BMTimeCalculate.h */, 151 | 2EAD69101CDDDF770086F0C3 /* BMTimeCalculate.m */, 152 | ); 153 | path = BMTimeCalculate; 154 | sourceTree = ""; 155 | }; 156 | /* End PBXGroup section */ 157 | 158 | /* Begin PBXNativeTarget section */ 159 | 2EAD68D71CDDDF2B0086F0C3 /* BMTimeCalculateDemo */ = { 160 | isa = PBXNativeTarget; 161 | buildConfigurationList = 2EAD69051CDDDF2B0086F0C3 /* Build configuration list for PBXNativeTarget "BMTimeCalculateDemo" */; 162 | buildPhases = ( 163 | 2EAD68D41CDDDF2B0086F0C3 /* Sources */, 164 | 2EAD68D51CDDDF2B0086F0C3 /* Frameworks */, 165 | 2EAD68D61CDDDF2B0086F0C3 /* Resources */, 166 | ); 167 | buildRules = ( 168 | ); 169 | dependencies = ( 170 | ); 171 | name = BMTimeCalculateDemo; 172 | productName = BMTimeCalculateDemo; 173 | productReference = 2EAD68D81CDDDF2B0086F0C3 /* BMTimeCalculateDemo.app */; 174 | productType = "com.apple.product-type.application"; 175 | }; 176 | 2EAD68F01CDDDF2B0086F0C3 /* BMTimeCalculateDemoTests */ = { 177 | isa = PBXNativeTarget; 178 | buildConfigurationList = 2EAD69081CDDDF2B0086F0C3 /* Build configuration list for PBXNativeTarget "BMTimeCalculateDemoTests" */; 179 | buildPhases = ( 180 | 2EAD68ED1CDDDF2B0086F0C3 /* Sources */, 181 | 2EAD68EE1CDDDF2B0086F0C3 /* Frameworks */, 182 | 2EAD68EF1CDDDF2B0086F0C3 /* Resources */, 183 | ); 184 | buildRules = ( 185 | ); 186 | dependencies = ( 187 | 2EAD68F31CDDDF2B0086F0C3 /* PBXTargetDependency */, 188 | ); 189 | name = BMTimeCalculateDemoTests; 190 | productName = BMTimeCalculateDemoTests; 191 | productReference = 2EAD68F11CDDDF2B0086F0C3 /* BMTimeCalculateDemoTests.xctest */; 192 | productType = "com.apple.product-type.bundle.unit-test"; 193 | }; 194 | 2EAD68FB1CDDDF2B0086F0C3 /* BMTimeCalculateDemoUITests */ = { 195 | isa = PBXNativeTarget; 196 | buildConfigurationList = 2EAD690B1CDDDF2B0086F0C3 /* Build configuration list for PBXNativeTarget "BMTimeCalculateDemoUITests" */; 197 | buildPhases = ( 198 | 2EAD68F81CDDDF2B0086F0C3 /* Sources */, 199 | 2EAD68F91CDDDF2B0086F0C3 /* Frameworks */, 200 | 2EAD68FA1CDDDF2B0086F0C3 /* Resources */, 201 | ); 202 | buildRules = ( 203 | ); 204 | dependencies = ( 205 | 2EAD68FE1CDDDF2B0086F0C3 /* PBXTargetDependency */, 206 | ); 207 | name = BMTimeCalculateDemoUITests; 208 | productName = BMTimeCalculateDemoUITests; 209 | productReference = 2EAD68FC1CDDDF2B0086F0C3 /* BMTimeCalculateDemoUITests.xctest */; 210 | productType = "com.apple.product-type.bundle.ui-testing"; 211 | }; 212 | /* End PBXNativeTarget section */ 213 | 214 | /* Begin PBXProject section */ 215 | 2EAD68D01CDDDF2B0086F0C3 /* Project object */ = { 216 | isa = PBXProject; 217 | attributes = { 218 | LastUpgradeCheck = 0730; 219 | ORGANIZATIONNAME = skyming; 220 | TargetAttributes = { 221 | 2EAD68D71CDDDF2B0086F0C3 = { 222 | CreatedOnToolsVersion = 7.3.1; 223 | DevelopmentTeam = 6Y97E3KB4K; 224 | }; 225 | 2EAD68F01CDDDF2B0086F0C3 = { 226 | CreatedOnToolsVersion = 7.3.1; 227 | DevelopmentTeam = 6Y97E3KB4K; 228 | TestTargetID = 2EAD68D71CDDDF2B0086F0C3; 229 | }; 230 | 2EAD68FB1CDDDF2B0086F0C3 = { 231 | CreatedOnToolsVersion = 7.3.1; 232 | DevelopmentTeam = 6Y97E3KB4K; 233 | TestTargetID = 2EAD68D71CDDDF2B0086F0C3; 234 | }; 235 | }; 236 | }; 237 | buildConfigurationList = 2EAD68D31CDDDF2B0086F0C3 /* Build configuration list for PBXProject "BMTimeCalculateDemo" */; 238 | compatibilityVersion = "Xcode 3.2"; 239 | developmentRegion = English; 240 | hasScannedForEncodings = 0; 241 | knownRegions = ( 242 | en, 243 | Base, 244 | ); 245 | mainGroup = 2EAD68CF1CDDDF2B0086F0C3; 246 | productRefGroup = 2EAD68D91CDDDF2B0086F0C3 /* Products */; 247 | projectDirPath = ""; 248 | projectRoot = ""; 249 | targets = ( 250 | 2EAD68D71CDDDF2B0086F0C3 /* BMTimeCalculateDemo */, 251 | 2EAD68F01CDDDF2B0086F0C3 /* BMTimeCalculateDemoTests */, 252 | 2EAD68FB1CDDDF2B0086F0C3 /* BMTimeCalculateDemoUITests */, 253 | ); 254 | }; 255 | /* End PBXProject section */ 256 | 257 | /* Begin PBXResourcesBuildPhase section */ 258 | 2EAD68D61CDDDF2B0086F0C3 /* Resources */ = { 259 | isa = PBXResourcesBuildPhase; 260 | buildActionMask = 2147483647; 261 | files = ( 262 | 2EAD68EB1CDDDF2B0086F0C3 /* LaunchScreen.storyboard in Resources */, 263 | 2EAD68E81CDDDF2B0086F0C3 /* Assets.xcassets in Resources */, 264 | 2EAD68E61CDDDF2B0086F0C3 /* Main.storyboard in Resources */, 265 | ); 266 | runOnlyForDeploymentPostprocessing = 0; 267 | }; 268 | 2EAD68EF1CDDDF2B0086F0C3 /* Resources */ = { 269 | isa = PBXResourcesBuildPhase; 270 | buildActionMask = 2147483647; 271 | files = ( 272 | ); 273 | runOnlyForDeploymentPostprocessing = 0; 274 | }; 275 | 2EAD68FA1CDDDF2B0086F0C3 /* Resources */ = { 276 | isa = PBXResourcesBuildPhase; 277 | buildActionMask = 2147483647; 278 | files = ( 279 | ); 280 | runOnlyForDeploymentPostprocessing = 0; 281 | }; 282 | /* End PBXResourcesBuildPhase section */ 283 | 284 | /* Begin PBXSourcesBuildPhase section */ 285 | 2EAD68D41CDDDF2B0086F0C3 /* Sources */ = { 286 | isa = PBXSourcesBuildPhase; 287 | buildActionMask = 2147483647; 288 | files = ( 289 | 2EAD68E31CDDDF2B0086F0C3 /* ViewController.m in Sources */, 290 | 2EAD68E01CDDDF2B0086F0C3 /* AppDelegate.m in Sources */, 291 | 2EAD68DD1CDDDF2B0086F0C3 /* main.m in Sources */, 292 | 2EAD69111CDDDF770086F0C3 /* BMTimeCalculate.m in Sources */, 293 | ); 294 | runOnlyForDeploymentPostprocessing = 0; 295 | }; 296 | 2EAD68ED1CDDDF2B0086F0C3 /* Sources */ = { 297 | isa = PBXSourcesBuildPhase; 298 | buildActionMask = 2147483647; 299 | files = ( 300 | 2EAD68F61CDDDF2B0086F0C3 /* BMTimeCalculateDemoTests.m in Sources */, 301 | ); 302 | runOnlyForDeploymentPostprocessing = 0; 303 | }; 304 | 2EAD68F81CDDDF2B0086F0C3 /* Sources */ = { 305 | isa = PBXSourcesBuildPhase; 306 | buildActionMask = 2147483647; 307 | files = ( 308 | 2EAD69011CDDDF2B0086F0C3 /* BMTimeCalculateDemoUITests.m in Sources */, 309 | ); 310 | runOnlyForDeploymentPostprocessing = 0; 311 | }; 312 | /* End PBXSourcesBuildPhase section */ 313 | 314 | /* Begin PBXTargetDependency section */ 315 | 2EAD68F31CDDDF2B0086F0C3 /* PBXTargetDependency */ = { 316 | isa = PBXTargetDependency; 317 | target = 2EAD68D71CDDDF2B0086F0C3 /* BMTimeCalculateDemo */; 318 | targetProxy = 2EAD68F21CDDDF2B0086F0C3 /* PBXContainerItemProxy */; 319 | }; 320 | 2EAD68FE1CDDDF2B0086F0C3 /* PBXTargetDependency */ = { 321 | isa = PBXTargetDependency; 322 | target = 2EAD68D71CDDDF2B0086F0C3 /* BMTimeCalculateDemo */; 323 | targetProxy = 2EAD68FD1CDDDF2B0086F0C3 /* PBXContainerItemProxy */; 324 | }; 325 | /* End PBXTargetDependency section */ 326 | 327 | /* Begin PBXVariantGroup section */ 328 | 2EAD68E41CDDDF2B0086F0C3 /* Main.storyboard */ = { 329 | isa = PBXVariantGroup; 330 | children = ( 331 | 2EAD68E51CDDDF2B0086F0C3 /* Base */, 332 | ); 333 | name = Main.storyboard; 334 | sourceTree = ""; 335 | }; 336 | 2EAD68E91CDDDF2B0086F0C3 /* LaunchScreen.storyboard */ = { 337 | isa = PBXVariantGroup; 338 | children = ( 339 | 2EAD68EA1CDDDF2B0086F0C3 /* Base */, 340 | ); 341 | name = LaunchScreen.storyboard; 342 | sourceTree = ""; 343 | }; 344 | /* End PBXVariantGroup section */ 345 | 346 | /* Begin XCBuildConfiguration section */ 347 | 2EAD69031CDDDF2B0086F0C3 /* Debug */ = { 348 | isa = XCBuildConfiguration; 349 | buildSettings = { 350 | ALWAYS_SEARCH_USER_PATHS = NO; 351 | CLANG_ANALYZER_NONNULL = YES; 352 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 353 | CLANG_CXX_LIBRARY = "libc++"; 354 | CLANG_ENABLE_MODULES = YES; 355 | CLANG_ENABLE_OBJC_ARC = YES; 356 | CLANG_WARN_BOOL_CONVERSION = YES; 357 | CLANG_WARN_CONSTANT_CONVERSION = YES; 358 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 359 | CLANG_WARN_EMPTY_BODY = YES; 360 | CLANG_WARN_ENUM_CONVERSION = YES; 361 | CLANG_WARN_INT_CONVERSION = YES; 362 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 363 | CLANG_WARN_UNREACHABLE_CODE = YES; 364 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 365 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 366 | COPY_PHASE_STRIP = NO; 367 | DEBUG_INFORMATION_FORMAT = dwarf; 368 | ENABLE_STRICT_OBJC_MSGSEND = YES; 369 | ENABLE_TESTABILITY = YES; 370 | GCC_C_LANGUAGE_STANDARD = gnu99; 371 | GCC_DYNAMIC_NO_PIC = NO; 372 | GCC_NO_COMMON_BLOCKS = YES; 373 | GCC_OPTIMIZATION_LEVEL = 0; 374 | GCC_PREPROCESSOR_DEFINITIONS = ( 375 | "DEBUG=1", 376 | "$(inherited)", 377 | ); 378 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 379 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 380 | GCC_WARN_UNDECLARED_SELECTOR = YES; 381 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 382 | GCC_WARN_UNUSED_FUNCTION = YES; 383 | GCC_WARN_UNUSED_VARIABLE = YES; 384 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 385 | MTL_ENABLE_DEBUG_INFO = YES; 386 | ONLY_ACTIVE_ARCH = YES; 387 | SDKROOT = iphoneos; 388 | TARGETED_DEVICE_FAMILY = "1,2"; 389 | }; 390 | name = Debug; 391 | }; 392 | 2EAD69041CDDDF2B0086F0C3 /* Release */ = { 393 | isa = XCBuildConfiguration; 394 | buildSettings = { 395 | ALWAYS_SEARCH_USER_PATHS = NO; 396 | CLANG_ANALYZER_NONNULL = YES; 397 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 398 | CLANG_CXX_LIBRARY = "libc++"; 399 | CLANG_ENABLE_MODULES = YES; 400 | CLANG_ENABLE_OBJC_ARC = YES; 401 | CLANG_WARN_BOOL_CONVERSION = YES; 402 | CLANG_WARN_CONSTANT_CONVERSION = YES; 403 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 404 | CLANG_WARN_EMPTY_BODY = YES; 405 | CLANG_WARN_ENUM_CONVERSION = YES; 406 | CLANG_WARN_INT_CONVERSION = YES; 407 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 408 | CLANG_WARN_UNREACHABLE_CODE = YES; 409 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 410 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 411 | COPY_PHASE_STRIP = NO; 412 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 413 | ENABLE_NS_ASSERTIONS = NO; 414 | ENABLE_STRICT_OBJC_MSGSEND = YES; 415 | GCC_C_LANGUAGE_STANDARD = gnu99; 416 | GCC_NO_COMMON_BLOCKS = YES; 417 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 418 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 419 | GCC_WARN_UNDECLARED_SELECTOR = YES; 420 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 421 | GCC_WARN_UNUSED_FUNCTION = YES; 422 | GCC_WARN_UNUSED_VARIABLE = YES; 423 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 424 | MTL_ENABLE_DEBUG_INFO = NO; 425 | SDKROOT = iphoneos; 426 | TARGETED_DEVICE_FAMILY = "1,2"; 427 | VALIDATE_PRODUCT = YES; 428 | }; 429 | name = Release; 430 | }; 431 | 2EAD69061CDDDF2B0086F0C3 /* Debug */ = { 432 | isa = XCBuildConfiguration; 433 | buildSettings = { 434 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 435 | INFOPLIST_FILE = BMTimeCalculateDemo/Info.plist; 436 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 437 | PRODUCT_BUNDLE_IDENTIFIER = com.skyming.demo.BMTimeCalculateDemo; 438 | PRODUCT_NAME = "$(TARGET_NAME)"; 439 | }; 440 | name = Debug; 441 | }; 442 | 2EAD69071CDDDF2B0086F0C3 /* Release */ = { 443 | isa = XCBuildConfiguration; 444 | buildSettings = { 445 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 446 | INFOPLIST_FILE = BMTimeCalculateDemo/Info.plist; 447 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 448 | PRODUCT_BUNDLE_IDENTIFIER = com.skyming.demo.BMTimeCalculateDemo; 449 | PRODUCT_NAME = "$(TARGET_NAME)"; 450 | }; 451 | name = Release; 452 | }; 453 | 2EAD69091CDDDF2B0086F0C3 /* Debug */ = { 454 | isa = XCBuildConfiguration; 455 | buildSettings = { 456 | BUNDLE_LOADER = "$(TEST_HOST)"; 457 | INFOPLIST_FILE = BMTimeCalculateDemoTests/Info.plist; 458 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 459 | PRODUCT_BUNDLE_IDENTIFIER = com.skyming.demo.BMTimeCalculateDemoTests; 460 | PRODUCT_NAME = "$(TARGET_NAME)"; 461 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BMTimeCalculateDemo.app/BMTimeCalculateDemo"; 462 | }; 463 | name = Debug; 464 | }; 465 | 2EAD690A1CDDDF2B0086F0C3 /* Release */ = { 466 | isa = XCBuildConfiguration; 467 | buildSettings = { 468 | BUNDLE_LOADER = "$(TEST_HOST)"; 469 | INFOPLIST_FILE = BMTimeCalculateDemoTests/Info.plist; 470 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 471 | PRODUCT_BUNDLE_IDENTIFIER = com.skyming.demo.BMTimeCalculateDemoTests; 472 | PRODUCT_NAME = "$(TARGET_NAME)"; 473 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BMTimeCalculateDemo.app/BMTimeCalculateDemo"; 474 | }; 475 | name = Release; 476 | }; 477 | 2EAD690C1CDDDF2B0086F0C3 /* Debug */ = { 478 | isa = XCBuildConfiguration; 479 | buildSettings = { 480 | INFOPLIST_FILE = BMTimeCalculateDemoUITests/Info.plist; 481 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 482 | PRODUCT_BUNDLE_IDENTIFIER = com.skyming.demo.BMTimeCalculateDemoUITests; 483 | PRODUCT_NAME = "$(TARGET_NAME)"; 484 | TEST_TARGET_NAME = BMTimeCalculateDemo; 485 | }; 486 | name = Debug; 487 | }; 488 | 2EAD690D1CDDDF2B0086F0C3 /* Release */ = { 489 | isa = XCBuildConfiguration; 490 | buildSettings = { 491 | INFOPLIST_FILE = BMTimeCalculateDemoUITests/Info.plist; 492 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 493 | PRODUCT_BUNDLE_IDENTIFIER = com.skyming.demo.BMTimeCalculateDemoUITests; 494 | PRODUCT_NAME = "$(TARGET_NAME)"; 495 | TEST_TARGET_NAME = BMTimeCalculateDemo; 496 | }; 497 | name = Release; 498 | }; 499 | /* End XCBuildConfiguration section */ 500 | 501 | /* Begin XCConfigurationList section */ 502 | 2EAD68D31CDDDF2B0086F0C3 /* Build configuration list for PBXProject "BMTimeCalculateDemo" */ = { 503 | isa = XCConfigurationList; 504 | buildConfigurations = ( 505 | 2EAD69031CDDDF2B0086F0C3 /* Debug */, 506 | 2EAD69041CDDDF2B0086F0C3 /* Release */, 507 | ); 508 | defaultConfigurationIsVisible = 0; 509 | defaultConfigurationName = Release; 510 | }; 511 | 2EAD69051CDDDF2B0086F0C3 /* Build configuration list for PBXNativeTarget "BMTimeCalculateDemo" */ = { 512 | isa = XCConfigurationList; 513 | buildConfigurations = ( 514 | 2EAD69061CDDDF2B0086F0C3 /* Debug */, 515 | 2EAD69071CDDDF2B0086F0C3 /* Release */, 516 | ); 517 | defaultConfigurationIsVisible = 0; 518 | }; 519 | 2EAD69081CDDDF2B0086F0C3 /* Build configuration list for PBXNativeTarget "BMTimeCalculateDemoTests" */ = { 520 | isa = XCConfigurationList; 521 | buildConfigurations = ( 522 | 2EAD69091CDDDF2B0086F0C3 /* Debug */, 523 | 2EAD690A1CDDDF2B0086F0C3 /* Release */, 524 | ); 525 | defaultConfigurationIsVisible = 0; 526 | }; 527 | 2EAD690B1CDDDF2B0086F0C3 /* Build configuration list for PBXNativeTarget "BMTimeCalculateDemoUITests" */ = { 528 | isa = XCConfigurationList; 529 | buildConfigurations = ( 530 | 2EAD690C1CDDDF2B0086F0C3 /* Debug */, 531 | 2EAD690D1CDDDF2B0086F0C3 /* Release */, 532 | ); 533 | defaultConfigurationIsVisible = 0; 534 | }; 535 | /* End XCConfigurationList section */ 536 | }; 537 | rootObject = 2EAD68D01CDDDF2B0086F0C3 /* Project object */; 538 | } 539 | -------------------------------------------------------------------------------- /BMTimeCalculateDemo/BMTimeCalculateDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /BMTimeCalculateDemo/BMTimeCalculateDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // BMTimeCalculateDemo 4 | // 5 | // Created by skyming on 16/5/7. 6 | // Copyright © 2016年 skyming. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /BMTimeCalculateDemo/BMTimeCalculateDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // BMTimeCalculateDemo 4 | // 5 | // Created by skyming on 16/5/7. 6 | // Copyright © 2016年 skyming. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "BMTimeCalculate.h" 11 | 12 | #define LOOPAGE 10000 13 | 14 | @interface AppDelegate () 15 | { 16 | NSMutableArray *test; 17 | double totalTime; 18 | double totalTimex; 19 | } 20 | @end 21 | 22 | @implementation AppDelegate 23 | 24 | 25 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 26 | // Override point for customization after application launch. 27 | 28 | CFTimeInterval start = CACurrentMediaTime(); 29 | // dosomething 30 | [NSThread sleepForTimeInterval:3.0f]; 31 | CFTimeInterval end = CACurrentMediaTime(); 32 | NSLog(@"时间损耗 = %f", end - start); 33 | 34 | clock_t startx = clock(); 35 | [NSThread sleepForTimeInterval:3.0f]; 36 | clock_t endx = clock(); 37 | NSLog(@"时间损耗 = %f", (double)(endx - startx)/CLOCKS_PER_SEC); 38 | 39 | test = [NSMutableArray array]; 40 | for (int i= 0; i < 100000000; i++) { 41 | [test addObject:@(i)]; 42 | } 43 | totalTime = 0.0f; 44 | totalTimex = 0.0f; 45 | 46 | // 同步方法测试 47 | // [self synTest1]; 48 | // [self synTest2]; 49 | for (int i = 0; i < 10; i ++) { 50 | [self synTest3]; 51 | } 52 | NSLog(@"\n"); 53 | NSLog(@"ForLoop Time-Block: %.3f ms", totalTime/10.0f); 54 | NSLog(@"Enumeration Time-Block: %.3f ms\n", totalTimex/10.0f); 55 | NSLog(@"\n"); 56 | 57 | // NSLog(@"4 start"); 58 | // [self syntest4]; 59 | 60 | totalTime = 0.0f; 61 | totalTimex = 0.0f; 62 | 63 | for (int i = 0; i < 10; i ++) { 64 | [self syntest5]; 65 | } 66 | NSLog(@"\n"); 67 | NSLog(@"ForLoop Time-Model: %.3f ms", totalTime/10.0f); 68 | NSLog(@"Enumeration Time-Model: %.3f ms\n", totalTimex/10.0f); 69 | NSLog(@"\n"); 70 | // 异步方法测试 71 | BMTimeCalculateModel *model = [BMTimeCalculateModel initWithTitle:@"动画操作"]; 72 | // 开始计时: 73 | [BMTimeCalculate startCalculate:model]; 74 | [UIView animateWithDuration:1.0f animations:^{ 75 | //结束计时: 76 | [BMTimeCalculate endCalculate:model]; 77 | }]; 78 | 79 | return YES; 80 | 81 | } 82 | 83 | - (void)synTest1 { 84 | double time; 85 | 86 | // A 87 | time = bmOperateConsumeCalculate(^{ 88 | NSLog(@"Block: %@", [NSThread currentThread]); 89 | for (int i = 0; i < LOOPAGE; i++) { 90 | NSLog(@"TestX %d", i); 91 | } 92 | }); 93 | NSLog(@"循环耗时Block: %.3f ms", time); 94 | 95 | BMTimeCalculateModel *model = [BMTimeCalculateModel initWithTitle:@"循环耗时Model"]; 96 | // 开始计时: 97 | [BMTimeCalculate startCalculate:model]; 98 | NSLog(@"Block: %@", [NSThread currentThread]); 99 | for (int i = 0; i < LOOPAGE; i++) { 100 | NSLog(@"TestX %d", i); 101 | } 102 | [BMTimeCalculate endCalculate:model]; 103 | 104 | } 105 | 106 | - (void)synTest2 { 107 | __block int i, j, count; 108 | double current = 0.0; 109 | __block double answer = 0.0; 110 | double elapsed = 0.0; 111 | int dim1 = 256; 112 | int dim2 = 256; 113 | int size = 4*dim1*dim2; 114 | 115 | //Allocatesome memory and warm it up 116 | double *array =(double*)malloc(size*sizeof(double)); 117 | for(i=0;i 10 | 11 | typedef void(^OperateConsumeBlock)(void); 12 | 13 | /** 14 | * Block 形式计算时间消耗,不适用异步线程,也不建议使用Block形式技术,根据测试在单纯加减操作情况,时间消耗误差 20% 左右 15 | * 16 | * @param operation 耗时操作 Block 17 | * 18 | * @return 消耗时间 单位毫秒,精确度纳秒 19 | */ 20 | extern double bmOperateConsumeCalculate (OperateConsumeBlock operation); 21 | 22 | 23 | 24 | /** 25 | * 测试单元对象 26 | */ 27 | @interface BMTimeCalculateModel : NSObject 28 | /** 29 | * 开始时间 30 | */ 31 | @property (nonatomic, assign) uint64_t startTime; 32 | /** 33 | * 结束时间 34 | */ 35 | @property (nonatomic, assign) uint64_t endTime; 36 | /** 37 | * 消耗的时间 38 | */ 39 | @property (nonatomic, assign) double elapsedTime; 40 | 41 | /** 42 | * 测试单元标题 43 | */ 44 | @property (nonatomic, copy) NSString *title; 45 | 46 | /** 47 | * 初始化测试单元对象 48 | * 49 | * @param title 测试单元标题 50 | * 51 | * @return 测试单元对象 52 | */ 53 | - (instancetype)initWithTitle:(NSString *)title; 54 | 55 | + (instancetype)initWithTitle:(NSString *)title; 56 | @end 57 | 58 | 59 | 60 | /** 61 | * 性能耗时计时测试类 62 | 用法: 63 | BMTimeCalculateModel *model = [BMTimeCalculateModel initWithTitle:@"回话列表数据获取"]; 64 | 开始计时:[BMTimeCalculate startCalculate:model]; 65 | 结束计时:[BMTimeCalculate endCalculate:model]; 66 | 输出单位毫秒(ms)、精确度微秒(μs) 67 | */ 68 | @interface BMTimeCalculate : NSObject 69 | 70 | /** 71 | * 开始计时测试 72 | * 73 | * @param model 计时测试单元 74 | */ 75 | + (void)startCalculate:(BMTimeCalculateModel *)model; 76 | /** 77 | * 结束计时测试 78 | * 79 | * @param model 计时测试单元 80 | */ 81 | + (void)endCalculate:(BMTimeCalculateModel *)model;; 82 | @end 83 | -------------------------------------------------------------------------------- /BMTimeCalculateDemo/BMTimeCalculateDemo/BMTimeCalculate/BMTimeCalculate.m: -------------------------------------------------------------------------------- 1 | // 2 | // BMTimeCalculate.m 3 | // GmacsIMKit 4 | // 5 | // Created by skyming on 16/1/12. 6 | // Copyright © 2016年 skyming. All rights reserved. 7 | // 8 | 9 | #import "BMTimeCalculate.h" 10 | #include 11 | 12 | // 单位换算 1s = 10^3 ms = 10^6 μs = 10^9 ns 13 | 14 | // 输出单位毫秒(ms),精确度纳秒(ns), 原生 mach_absolute_times 输入, 15 | static double subtractTimes(uint64_t start, uint64_t end) 16 | { 17 | static double conversion = 0.0; 18 | uint64_t elapsed = end - start; 19 | 20 | if (start > end) { 21 | printf ("Error: start > end \n"); 22 | return -1.0f; 23 | } 24 | 25 | if(conversion == 0.0) 26 | { 27 | mach_timebase_info_data_t info; 28 | kern_return_t __error = mach_timebase_info(&info); //Convert the timebaseinto seconds 29 | 30 | if(__error != KERN_SUCCESS) 31 | { 32 | printf ("Error: mach_timebase_info failed\n"); 33 | return -1.0f; 34 | } 35 | conversion = 1e-6 * (double) info.numer / (double) info.denom; 36 | } 37 | return conversion * (double)elapsed; // ms 38 | } 39 | 40 | //???: 通过Block形式 计算,同样的操作比 model 形式 损耗 20% 左右 41 | double bmOperateConsumeCalculate (OperateConsumeBlock operation) 42 | { 43 | uint64_t start = mach_absolute_time (); 44 | operation(); 45 | uint64_t end = mach_absolute_time (); 46 | return subtractTimes(start, end); 47 | } 48 | 49 | 50 | @implementation BMTimeCalculateModel 51 | 52 | - (instancetype)initWithTitle:(NSString *)title { 53 | if (self = [super init]) { 54 | _title = title; 55 | } 56 | return self; 57 | } 58 | + (instancetype)initWithTitle:(NSString *)title { 59 | return [[BMTimeCalculateModel alloc]initWithTitle:title]; 60 | } 61 | @end 62 | 63 | 64 | @implementation BMTimeCalculate 65 | 66 | //输出单位毫秒(ms)、精确度微秒(μs) 67 | + (void)startCalculate:(BMTimeCalculateModel *)model { 68 | model.startTime = mach_absolute_time(); // ns 69 | NSLog(@"%@ - 开始时间 - %llu", model.title, model.startTime/1000); // μs 70 | } 71 | 72 | + (void)endCalculate:(BMTimeCalculateModel *)model { 73 | model.endTime = mach_absolute_time(); // ns 74 | model.elapsedTime = subtractTimes(model.startTime, model.endTime); 75 | NSLog(@"%@ - 结束时间 - %llu", model.title, model.endTime/1000); // μs 76 | NSLog(@"%@ - 时间消耗 - %.3f ms", model.title, model.elapsedTime); 77 | } 78 | 79 | @end 80 | 81 | -------------------------------------------------------------------------------- /BMTimeCalculateDemo/BMTimeCalculateDemo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /BMTimeCalculateDemo/BMTimeCalculateDemo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /BMTimeCalculateDemo/BMTimeCalculateDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /BMTimeCalculateDemo/BMTimeCalculateDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // BMTimeCalculateDemo 4 | // 5 | // Created by skyming on 16/5/7. 6 | // Copyright © 2016年 skyming. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /BMTimeCalculateDemo/BMTimeCalculateDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // BMTimeCalculateDemo 4 | // 5 | // Created by skyming on 16/5/7. 6 | // Copyright © 2016年 skyming. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view, typically from a nib. 20 | } 21 | 22 | - (void)didReceiveMemoryWarning { 23 | [super didReceiveMemoryWarning]; 24 | // Dispose of any resources that can be recreated. 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /BMTimeCalculateDemo/BMTimeCalculateDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // BMTimeCalculateDemo 4 | // 5 | // Created by skyming on 16/5/7. 6 | // Copyright © 2016年 skyming. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /BMTimeCalculateDemo/BMTimeCalculateDemoTests/BMTimeCalculateDemoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // BMTimeCalculateDemoTests.m 3 | // BMTimeCalculateDemoTests 4 | // 5 | // Created by skyming on 16/5/7. 6 | // Copyright © 2016年 skyming. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BMTimeCalculateDemoTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation BMTimeCalculateDemoTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /BMTimeCalculateDemo/BMTimeCalculateDemoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /BMTimeCalculateDemo/BMTimeCalculateDemoUITests/BMTimeCalculateDemoUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // BMTimeCalculateDemoUITests.m 3 | // BMTimeCalculateDemoUITests 4 | // 5 | // Created by skyming on 16/5/7. 6 | // Copyright © 2016年 skyming. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BMTimeCalculateDemoUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation BMTimeCalculateDemoUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /BMTimeCalculateDemo/BMTimeCalculateDemoUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Baoming Bai 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # iOS-Performance-Optimization 2 | 关于iOS 性能优化梳理: 3 | 基本工具、业务优化、内存优化、卡顿优化、布局优化、电量优化、 安装包瘦身、启动优化、网络优化等 4 | 5 | 6 | #### iOS 官方文档 7 | > 专题内容比较多,后面细分内容会有部分重复。 8 | * [Performance 专题](https://developer.apple.com/library/content/navigation/#section=Topics&topic=Performance) 9 | * [Core Animation Programming Guide](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreAnimation_guide) 10 | 11 | 12 | #### iOS 性能优化相关书籍 13 | * [Pro iOS Apps Performance Optimization](http://download.csdn.net/detail/tskyming/9831453) 14 | * [High Performance iOS Apps](http://download.csdn.net/detail/tskyming/9831465) 15 | * [iOS-Core-Animation-Advanced-Techniques](https://github.com/AttackOnDobby/iOS-Core-Animation-Advanced-Techniques) 16 | 17 | #### Instruments 工具相关 18 | * [Instruments User Guide](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/index.html) [中文翻译-PDF](http://cdn.cocimg.com/bbs/attachment/Fid_6/6_24457_90eabb4ed5b3863.pdf) 19 | * [Instruments之Leaks学习](http://www.cnblogs.com/lxlx1798/p/6933485.html) 20 | * [Instruments学习之Allocations](http://www.cnblogs.com/lxlx1798/p/6933195.html) 21 | * [instrument之Time Profiler总结](http://www.cnblogs.com/lxlx1798/p/6933604.html) 22 | * [Instruments学习之Core Animation学习](http://www.cnblogs.com/lxlx1798/p/6933364.html) 23 | * [Instruments之Activity Monitor使用入门](http://www.cnblogs.com/lxlx1798/p/6933141.html) 24 | 25 | #### GMTC-2018 PPT 26 | * [LinkedIn移动应用的性能优化之道](https://ppt.geekbang.org/slide/show?cid=31&pid=1495) 27 | * [美团客户端监控与异常排查实践](https://ppt.geekbang.org/slide/show?cid=31&pid=1500) 28 | * [爱奇艺APP极致体验之路](https://ppt.geekbang.org/slide/show?cid=31&pid=1497) 29 | * [大前端时代前端监控的最佳实践](https://ppt.geekbang.org/slide/show?cid=31&pid=1496) 30 | * [性能优化与监控专题PPT](https://gmtc.infoq.cn/2019/beijing/) 31 | 32 | #### 综合篇 33 | * [WWDC2012-235-iOS APP Performance:Responsiveness](https://developer.apple.com/videos/play/wwdc2012/235) 34 | * [微信读书iOS性能优化](http://wereadteam.github.io/2016/05/03/WeRead-Performance/) 35 | * [微信读书 iOS 质量保证及性能监控](http://wereadteam.github.io/2016/12/12/Monitor/) 36 | * [深入剖析 iOS 性能优化](https://ming1016.github.io/2017/06/20/deeply-ios-performance-optimization/) 37 | * [魔窗研发副总裁沈哲:移动端SDK的优化之路](http://blog.csdn.net/magicwindow/article/details/51423463) 38 | * [搜狗输入法 iOS 版开发与优化实践](http://www.cocoachina.com/design/20160905/17483.html)[PPT](https://github.com/MDCC2016/iOS-Session-Slides/blob/master/%E6%90%9C%E7%8B%97%E8%BE%93%E5%85%A5%E6%B3%95%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%E5%AE%9E%E8%B7%B5-%E6%9D%8E%E8%85%BE%E6%9D%B0.pdf) 39 | * [蘑菇街 App 的稳定性与性能实践](http://www.infoq.com/cn/presentations/stability-and-performance-of-mogujie-app)[PPT](https://sanwen8.cn/p/6e5c888.html) 40 | * [⼿淘iOS性能优化探索](http://pstatic.geekbang.org/pdf/593a53d813cef.pdf?e=1497499485&token=eHNJKRTldoRsUX0uCP9M3icEhpbyh3VF9Nrk5UPM:sa-xp_aIeIhtiWbqR-hY4ImMzFc=) 41 | * [iOS App 稳定性指标及监测](https://juejin.im/post/58ca0832a22b9d006418fe43) 42 | 43 | #### 内存优化 44 | * [Memory Usage Performance Guidelines](https://developer.apple.com/library/content/documentation/Performance/Conceptual/ManagingMemory/ManagingMemory.html#//apple_ref/doc/uid/10000160i) 45 | * [WWDC-2018-416](https://developer.apple.com/videos/play/wwdc2018/416/)[中文翻译](https://juejin.im/post/5b23dafee51d4558e03cbf4f) 46 | * [探索iOS内存分配](https://juejin.im/post/5a5e13c45188257327399e19) 47 | * [iOS微信内存监控](http://wetest.qq.com/lab/view/367.html?from=content_juejin) 48 | * [内存管理及优化(上)-QQ浏览器](https://www.imooc.com/video/11075) 49 | * [内存管理及优化(下)-QQ浏览器](https://www.imooc.com/video/11076) 50 | * [OOM探究:XNU 内存状态管理](https://www.jianshu.com/p/4458700a8ba8) 51 | * [OOMDetector 内存监控(腾讯开源)](https://github.com/Tencent/OOMDetector) 52 | 53 | #### 卡顿优化 54 | * [UIKit性能调优实战讲解](http://www.cocoachina.com/ios/20160208/15238.html?utm_source=tuicool&utm_medium=referral) 55 | * [QQ空间掉帧率优化实战](http://wetest.qq.com/lab/view/354.html) 56 | * [实现 60fps 的网易云音乐首页](https://mp.weixin.qq.com/s?__biz=MzA4MzEwOTkyMQ==&mid=2667379069&idx=1&sn=376d9ef2261cf13e930406f1c35d3569) 57 | * [iOS 保持界面流畅的技巧](http://blog.ibireme.com/2015/11/12/smooth_user_interfaces_for_ios/) 58 | * [iOS UI性能优化总结](http://www.cocoachina.com/ios/20180412/22990.html) 59 | * [微信iOS卡顿监控系统](http://mp.weixin.qq.com/s?__biz=MzAwNDY1ODY2OQ%3D%3D&idx=1&mid=207890859&scene=23&sn=e98dd604cdb854e7a5808d2072c29162&srcid=0921FzoCw9j1W7n4uFYKuarC#rd) 60 | * [iOS-卡顿检测](http://www.cnblogs.com/gatsbywang/p/5555200.html) 61 | * [iOS监控:卡顿检测](http://ios.jobbole.com/93085/) 62 | * [iOS应用UI线程卡顿监控](https://mp.weixin.qq.com/s?__biz=MzI5MjEzNzA1MA==&mid=2650264136&idx=1&sn=052c1db8131d4bed8458b98e1ec0d5b0&chksm=f406837dc3710a6b49e76ce3639f671373b553e8a91b544e82bb8747e9adc7985fea1093a394#rd) 63 | 64 | #### 布局优化 65 | TODO: 66 | 67 | #### 电量优化 68 | * [Guide - Energy Efficiency Guide for iOS Apps](https://developer.apple.com/library/content/documentation/Performance/Conceptual/EnergyGuide-iOS/index.html#//apple_ref/doc/uid/TP40015243) 69 | * [WWDC2017 - Writing Energy Efficient Apps](https://developer.apple.com/videos/play/wwdc2017/238/) 70 | * [iOS 常见耗电量检测方案调研](https://github.com/ChenYilong/iOSBlog/issues/10) 71 | * [教你开发省电的 iOS app(WWDC17 观后)](http://www.jianshu.com/p/f0dc653d04ca) 72 | * [浅析移动蜂窝网络的特点及其省电方案](https://juejin.im/post/5a0c5af051882578da0d6925) 73 | * [iOS电量测试实践](https://mp.weixin.qq.com/s/q39BHIWsbdNeqfH85EOkIQ) 74 | * [iOS进阶--App功耗优化看这篇就够了](http://www.cocoachina.com/ios/20171204/21413.html) 75 | 76 | #### 启动优化 77 | * [WWDC2016-406-Optimizing App Startup Time](https://developer.apple.com/videos/play/wwdc2016/406) 78 | * [WWDC2017-413-App Startup Time:Past,Present,and Future](https://developer.apple.com/videos/play/wwdc2017/413) 79 | * [如何精准度量iOSAPP启动时间](https://www.jianshu.com/p/c14987eee107) 80 | * [优化 App 的启动时间-杨萧玉](http://yulingtianxia.com/blog/2016/10/30/Optimizing-App-Startup-Time) 81 | * [iOS客户端启动速度优化-今日头条](https://techblog.toutiao.com/2017/01/17/iosspeed/#more) 82 | * [iOS App 启动性能优化-WiFi管家](https://mp.weixin.qq.com/s/Kf3EbDIUuf0aWVT-UCEmbA) 83 | * [iOS App如何优化启动时间-Facebook](http://www.cocoachina.com/ios/20160104/14870.html) 84 | * [iOS 启动速度优化-百度输入法](http://www.infoq.com/cn/presentations/ios-typewriting-start-speed-optimization) 85 | * [obj中国-Mach-O 可执行文件](https://objccn.io/issue-6-3/) 86 | * [iOS app启动速度研究实践](https://zhuanlan.zhihu.com/p/38183046?from=1086193010&wm=3333_2001&weiboauthoruid=1690182120) 87 | * [iOS App冷启动治理:来自美团外卖的实践](https://mp.weixin.qq.com/s/jN3jaNrvXczZoYIRCWZs7w) 88 | * [脉脉iOS如何启动秒开](https://zhuanlan.zhihu.com/p/396550853) 89 | 90 | #### 体积优化 91 | * [iOS微信安装包瘦身](http://mp.weixin.qq.com/s?__biz=MzAwNDY1ODY2OQ==&mid=207986417&idx=1&sn=77ea7d8e4f8ab7b59111e78c86ccfe66&scene=24&srcid=0921TTAXHGHWKqckEHTvGzoA#rd) 92 | * [今日头条IPA安装包的优化](https://techblog.toutiao.com/2016/12/27/iphone/) 93 | * [iOS瘦身之删除FrameWork中无用mach-O文件](http://www.infoq.com/cn/articles/ios-thinning-delete-unnecessary-mach-o) 94 | * [基于clang插件的一种iOS包大小瘦身方案](http://www.infoq.com/cn/articles/clang-plugin-ios-app-size-reducing) 95 | * [iOS可执行文件瘦身方法](http://blog.cnbang.net/tech/2544/) 96 | * [iOS图片优化方案](http://crespoxiao.github.io/2016/11/12/iOS%E5%9B%BE%E7%89%87%E4%BC%98%E5%8C%96%E6%96%B9%E6%A1%88/) 97 | * [滴滴出行 iOS 端瘦身实践的 Slides](https://ming1016.github.io/2017/06/12/gmtc-ios-slimming-practice/) 98 | 99 | #### 网络优化 100 | * [美团点评移动网络优化实践](http://tech.meituan.com/SharkSDK.html) 101 | * [开源版HttpDNS方案详解](http://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=209805123&idx=1&sn=ced8d67c3e2cc3ca38ef722949fa21f8) 102 | * [携程App的网络性能优化实践](http://www.infoq.com/cn/articles/how-ctrip-improves-app-networking-performance) 103 | * [2016年携程App网络服务通道治理和性能优化实践](http://www.infoq.com/cn/articles/app-network-service-and-performance-optimization-of-ctrip) 104 | * [蘑菇街App Chromium网络栈实践](http://www.infoq.com/cn/articles/mogujie-app-chromium-network-layer) 105 | * [蘑菇街高并发多终端无线网关实践](http://www.infoq.com/cn/presentations/mogujie-high-concurrent-multi-terminal-wireless-gateway-practice) 106 | * [移动 APP 网络优化概述](http://blog.cnbang.net/tech/3531/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io) 107 | 108 | #### 编译优化 109 | * [Optimizing-Swift-Build-Times](https://github.com/fastred/Optimizing-Swift-Build-Times) 110 | 111 | #### APM 112 | * [移动端监控体系之技术原理剖析](http://ios.jobbole.com/92988/) 113 | * [网易 - NeteaseAPM iOS SDK技术实现分享](http://mp.weixin.qq.com/s?__biz=MzA3ODg4MDk0Ng==&mid=2651112215&idx=1&sn=9cc5b5fa630542a6d4b7a5626e35217a#rd) 114 | * [网易乐得 - iOS无埋点数据SDK实践之路](http://www.jianshu.com/p/69ce01e15042) 115 | * [听云 - 移动端 APM 产品研发技能](http://www.infoq.com/cn/presentations/mobile-terminal-apm-product-development-skills) 116 | * [听云 - 移动 App 性能监测](http://www.infoq.com/cn/presentations/mobile-app-performance-monitoring-practice?utm_source=presentations_about_mobile&utm_medium=link&utm_campaign=mobile) 117 | * [iOS 性能监控 SDK —— Wedjat(华狄特)开发过程的调研和整理](https://github.com/aozhimin/iOS-Monitor-Platform) 118 | * [揭秘 APM iOS SDK 的核心技术](https://github.com/iOS-APM/iOS-APM-Secrets) 119 | * [iOS-Monitor-Resources](https://github.com/aozhimin/iOS-Monitor-Resources) 120 | * [iOS 流量监控分析](https://juejin.im/post/5b1602906fb9a01e3542f08c) 121 | * [小试Xcode逆向:app内存监控原理初探](http://ddrccw.github.io/2017/12/30/reverse-xcode-with-lldb-and-hopper-disassembler) 122 | * [APMCon-2016演讲实录](http://apmcon.cn/2016/index.html#yjsl) 123 | * [360移动端性能监控实践QDAS-APM(iOS篇)](https://mp.weixin.qq.com/s/Vq0TDiLbexxBlqlf_lilnQ) 124 | * [移动端性能监控方案Hertz](https://tech.meituan.com/2016/12/19/hertz.html) 125 | 126 | #### 调试 & Crash 127 | * [iOS 项目开发过程中用到的高级调试技巧,涉及三方库动态调试、静态分析和反编译等领域](https://github.com/aozhimin/iOS-Debug-Hacks) 128 | * [Understanding and Analyzing Application Crash Reports](https://developer.apple.com/library/content/technotes/tn2151/_index.html) 129 | 130 | 131 | #### 相关开源库 132 | ##### 网络 133 | * [HTTPDNSLib-for-iOS](https://github.com/CNSRE/HTTPDNSLib-for-iOS) 134 | * [HTTPDNSLib-for-Andorod](https://github.com/CNSRE/HTTPDNSLib) 135 | * [NetworkEye](https://github.com/coderyi/NetworkEye/blob/master/README_Chinese.md) 136 | 137 | ##### 内存 138 | * [FBMemoryProfiler](https://github.com/facebook/FBMemoryProfiler) 139 | * [iOS Memory Budget Test](https://github.com/Split82/iOSMemoryBudgetTest) 140 | 141 | ##### 卡顿 142 | * [PerformanceMonitor-Runloop](https://github.com/suifengqjn/PerformanceMonitor) 143 | * [GYMonitor-FPS](https://github.com/featuretower/GYMonitor) 144 | 145 | ##### 瘦身 146 | * [LSUnusedResources](https://github.com/tinymind/LSUnusedResources) 147 | * [LinkMap](https://github.com/huanxsd/LinkMap) 148 | 149 | #### APM 150 | * [btrace](https://github.com/bytedance/btrace) 151 | * [iOS-System-Services](https://github.com/iOS-APM/iOS-System-Services) 152 | * [System Monitor](https://github.com/iOS-APM/SystemMonitor) 153 | * [PerformanceTestingHelper](https://github.com/ArmsZhou/PerformanceTestingHelper) 154 | * [GT](https://github.com/Tencent/GT) 155 | * [GodEye](https://github.com/zixun/GodEye) 156 | * [ArgusAPM](https://github.com/Qihoo360/ArgusAPM) 157 | * [AppleTrace](https://github.com/everettjf/AppleTrace) 158 | * [matrix](https://github.com/Tencent/matrix) 159 | * [MTHawkeye](https://github.com/meitu/MTHawkeye) 160 | 161 | --------------------------------------------------------------------------------