├── .gitignore ├── GNUmakefile ├── GNUmakefile.tests ├── LICENSE ├── NativeZWRChecker ├── NativeZWRCheckeriPhone-Info.plist ├── main.m └── sourcedumper.py ├── README.markdown ├── Source ├── MANotificationCenterAdditions.h ├── MANotificationCenterAdditions.m ├── MAWeakArray.h ├── MAWeakArray.m ├── MAWeakDictionary.h ├── MAWeakDictionary.m ├── MAZeroingWeakProxy.h ├── MAZeroingWeakProxy.m ├── MAZeroingWeakRef.h ├── MAZeroingWeakRef.m ├── MAZeroingWeakRefNativeZWRNotAllowedTable.h └── main.m ├── ZeroingWeakRef.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ └── mikeash.xcuserdatad │ └── WorkspaceState.xcuserstate └── ZeroingWeakRef_Prefix.pch /.gitignore: -------------------------------------------------------------------------------- 1 | # xcode noise 2 | *.mode1v3 3 | *.pbxuser 4 | *.pyc 5 | *~.nib/ 6 | build/* 7 | xcuserdata/ 8 | 9 | # osx noise 10 | .DS_Store 11 | 12 | *xcuserdata* 13 | -------------------------------------------------------------------------------- /GNUmakefile: -------------------------------------------------------------------------------- 1 | include $(GNUSTEP_MAKEFILES)/common.make 2 | 3 | CC=clang 4 | 5 | LIBRARY_NAME = libweakref 6 | libweakref_HEADER_FILES_DIR = Source 7 | libweakref_HEADER_FILES = \ 8 | MAZeroingWeakRef.h \ 9 | MAWeakArray.h \ 10 | MAWeakDictionary.h \ 11 | MAZeroingWeakProxy.h \ 12 | MAZeroingWeakRefNativeZWRNotAllowedTable.h 13 | libweakref_HEADER_FILES_INSTALL_DIR = MAZeroingWeakRef 14 | 15 | libweakref_OBJC_FILES = \ 16 | Source/MAWeakArray.m \ 17 | Source/MAWeakDictionary.m \ 18 | Source/MAZeroingWeakProxy.m \ 19 | Source/MAZeroingWeakRef.m 20 | 21 | libweakref_RESOURCE_FILES = 22 | libweakref_CFLAGS = -fblocks -fobjc-nonfragile-abi -g -Os 23 | libweakref_OBJCFLAGS = -fblocks -fobjc-nonfragile-abi -DNS_BLOCKS_AVAILABLE -g -Os 24 | libweakref_OBJC_LIBS = 25 | libweakref_LDFLAGS = -g -Os 26 | libweakref_INCLUDE_DIRS = -ISource/ 27 | 28 | include $(GNUSTEP_MAKEFILES)/library.make 29 | 30 | -------------------------------------------------------------------------------- /GNUmakefile.tests: -------------------------------------------------------------------------------- 1 | include $(GNUSTEP_MAKEFILES)/common.make 2 | 3 | CC=clang 4 | 5 | TOOL_NAME = tests 6 | tests_HEADER_FILES_DIR = Source 7 | tests_HEADER_FILES = \ 8 | MAZeroingWeakRef.h \ 9 | MAWeakArray.h \ 10 | MAWeakDictionary.h \ 11 | MAZeroingWeakProxy.h \ 12 | MAZeroingWeakRefNativeZWRNotAllowedTable.h 13 | 14 | tests_OBJC_FILES = \ 15 | Source/main.m \ 16 | Source/MAWeakArray.m \ 17 | Source/MAWeakDictionary.m \ 18 | Source/MAZeroingWeakProxy.m \ 19 | Source/MAZeroingWeakRef.m 20 | 21 | tests_CFLAGS = -fblocks -fobjc-nonfragile-abi -g -Os 22 | tests_OBJCFLAGS = -fblocks -fobjc-nonfragile-abi -DNS_BLOCKS_AVAILABLE -g -Os 23 | tests_OBJC_LIBS = 24 | tests_LDFLAGS = -g -Os 25 | tests_INCLUDE_DIRS = -ISource/ 26 | 27 | include $(GNUSTEP_MAKEFILES)/tool.make 28 | 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MAZeroingWeakRef and all code associated with it is distributed under a BSD license, as listed below. 2 | 3 | 4 | Copyright (c) 2010, Michael Ash 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 8 | 9 | Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | 11 | Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 12 | 13 | Neither the name of Michael Ash nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /NativeZWRChecker/NativeZWRCheckeriPhone-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFiles 12 | 13 | CFBundleIdentifier 14 | com.mikeash.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1.0 27 | LSRequiresIPhoneOS 28 | 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 | -------------------------------------------------------------------------------- /NativeZWRChecker/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // NativeZWRCheckeriPhone 4 | // 5 | // Created by Michael Ash on 10/15/11. 6 | // Copyright (c) 2011 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #import 13 | #import 14 | #import 15 | #import 16 | #import 17 | #import 18 | 19 | 20 | @implementation NSObject (HackHackHackYourBoat) 21 | 22 | - (BOOL)_isDeallocating { return NO; } 23 | 24 | @end 25 | 26 | static void Check(void) 27 | { 28 | [NSAutoreleasePool new]; 29 | 30 | char *badClassNames[] = { 31 | "NSProxy", 32 | "__NSPlaceholderArray", 33 | "NSSubrangeData", 34 | "NSJSONSerialization", 35 | "NSCGImageSnapshotRep", 36 | "FEOpenCLContext", 37 | "_PFEncodedData", 38 | "NSPropertyListSerialization", 39 | "FEContext", 40 | "NSPersistentStore", 41 | "HICocoaWindowAdapter", 42 | "NSApplication", 43 | "NSCachedImageRep", 44 | "NSCIImageRep", 45 | "NSCGImageRep", 46 | "NSPasteboard", 47 | "NSFileVersion", 48 | "NSIconRefImageRep", 49 | "NSIconRefBitmapImageRep", 50 | "NSColorPanel", 51 | "NSFontDescriptor", 52 | "NSKnownKeysDictionary", 53 | "__NSPlaceholderSet", 54 | "NSCustomImageRep", 55 | "_NSTemporaryObjectID2", 56 | "NSTemporaryObjectID", 57 | "NSKeyedUnarchiver", 58 | "NSPICTImageRep", 59 | "_NSZombie_", 60 | "NSKnownKeysMappingStrategy2", 61 | "__NSGenericDeallocHandler", 62 | "NSPDFImageRep", 63 | "NSMessageBuilder", 64 | "NSDistributedLock", 65 | "NSKeyedArchiver", 66 | "__CFNotification", 67 | "NSNavFBETopLevelNode", 68 | "Protocol", 69 | "NSTreeNode", 70 | "NSBitmapImageRep", 71 | "NSNotification", 72 | "NSDocumentRevisionsPlaceholderView", 73 | "__NSPlaceholderDictionary", 74 | "DDNonTerminal", 75 | "NSAtomicStoreCacheNode", 76 | "NSViewTemplate", 77 | "__NSPlaceholderOrderedSet", 78 | "Object", 79 | "NSLeafProxy", 80 | "__IncompleteProtocol", 81 | "NSHTTPCookie", 82 | "_PFEncodedString", 83 | "NSEPSImageRep", 84 | "_PFEncodedArray", 85 | "DOMObject", 86 | "UIProgressBar", 87 | "UIWebTextView", 88 | "BasicAccount", 89 | "UIWebBrowserView", 90 | "UIPasteboard", 91 | "_UIDefinitionService", 92 | "_UIDateLabelCache", 93 | "ABPersonLinker", 94 | "WebInspectorWindowController", 95 | "UIPrintInteractionController", 96 | "_TMBlockDebugger", 97 | "UIDocument", 98 | "UISplitViewController", 99 | "MCDependencyManager", 100 | "DADConnection", 101 | "UIApplication", 102 | "UIPrintInfo", 103 | "UIPopoverController", 104 | "UIURLResolver", 105 | "NSSpeechSynthesizer" 106 | }; 107 | 108 | void (*NSApplicationLoadFptr)(void) = dlsym(RTLD_DEFAULT, "NSApplicationLoad"); 109 | if(NSApplicationLoadFptr) 110 | NSApplicationLoadFptr(); 111 | 112 | int count = objc_getClassList(NULL, 0); 113 | Class *classes = malloc(count * sizeof(*classes)); 114 | objc_getClassList(classes, count); 115 | 116 | NSMutableArray *results = [NSMutableArray array]; 117 | 118 | fprintf(stderr, "starting...\n"); 119 | for(int i = 0; i < count; i++) 120 | { 121 | Class c = classes[i]; 122 | 123 | BOOL isBad = NO; 124 | for(Class toCheck = c; toCheck; toCheck = class_getSuperclass(toCheck)) 125 | { 126 | for(unsigned i = 0; i < sizeof(badClassNames) / sizeof(*badClassNames); i++) 127 | { 128 | if(strcmp(class_getName(toCheck), badClassNames[i]) == 0) 129 | isBad = YES; 130 | } 131 | } 132 | if(isBad) 133 | continue; 134 | 135 | id instance = [[c alloc] init]; 136 | 137 | BOOL (*allowsWeakReference)(id, SEL); 138 | SEL allowsWeakReferenceSEL = @selector(allowsWeakReference); 139 | allowsWeakReference = (BOOL (*)(id, SEL))class_getMethodImplementation(c, allowsWeakReferenceSEL); 140 | if((IMP)allowsWeakReference != class_getMethodImplementation(c, @selector(thisHadBetterBeUndefinedIReallyHopeSo))) 141 | { 142 | BOOL allows = allowsWeakReference(instance, allowsWeakReferenceSEL); 143 | if(!allows) 144 | { 145 | const char *name = class_getName(c); 146 | NSMutableData *sha = [NSMutableData dataWithLength: CC_SHA1_DIGEST_LENGTH]; 147 | CC_SHA1(name, (int)strlen(name), [sha mutableBytes]); 148 | 149 | NSDictionary *d = [NSDictionary dictionaryWithObjectsAndKeys: 150 | sha, @"sha", 151 | [NSString stringWithUTF8String: name], @"name", 152 | nil]; 153 | [results addObject: d]; 154 | } 155 | } 156 | } 157 | fprintf(stderr, "done!\n"); 158 | 159 | NSData *data = [NSPropertyListSerialization dataFromPropertyList: results format: NSPropertyListXMLFormat_v1_0 errorDescription: NULL]; 160 | [[NSFileHandle fileHandleWithStandardOutput] writeData: data]; 161 | } 162 | 163 | int main(int argc, char *argv[]) 164 | { 165 | int (*UIApplicationMainFptr)(int, char **, void *, void *) = dlsym(RTLD_DEFAULT, "UIApplicationMain"); 166 | if(UIApplicationMainFptr) 167 | { 168 | dispatch_async(dispatch_get_main_queue(), ^{ Check(); }); 169 | UIApplicationMainFptr(argc, argv, NULL, NULL); 170 | } 171 | else 172 | { 173 | Check(); 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /NativeZWRChecker/sourcedumper.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | iOSPlist = """ 4 | 5 | 6 | 7 | 8 | name 9 | __NSOperationInternal 10 | sha 11 | 12 | ROSeGwWpNKnZxacFFj1PFUGoRSQ= 13 | 14 | 15 | 16 | name 17 | __NSStackBlock__ 18 | sha 19 | 20 | 3papHp41j4ZHdNNrNkFTcEBSr8s= 21 | 22 | 23 | 24 | name 25 | NSPort 26 | sha 27 | 28 | We3vJYzFNeejp1rM03UIQ7IK7rI= 29 | 30 | 31 | 32 | name 33 | NSMachPort 34 | sha 35 | 36 | sEAJodm0DwS2BNbVe53fngii5Lc= 37 | 38 | 39 | 40 | name 41 | NSMessagePort 42 | sha 43 | 44 | VHdluyievZ9dDDlwW+dlzDzMSgY= 45 | 46 | 47 | 48 | name 49 | __NSFinalizingBlock__ 50 | sha 51 | 52 | 3AZZFtRa6m+OCKyJrAtzLGJn/wA= 53 | 54 | 55 | 56 | name 57 | NSBlock 58 | sha 59 | 60 | BQpaL8Om1fvPzIXyL+oW67/PnlI= 61 | 62 | 63 | 64 | name 65 | __NSStackBlock 66 | sha 67 | 68 | zRs7gD8UnN6tGEvpRLoBXwiY1ow= 69 | 70 | 71 | 72 | name 73 | __NSAutoBlock 74 | sha 75 | 76 | lyAIsod346R+vjRvhCmmISp/zA4= 77 | 78 | 79 | 80 | name 81 | __NSFinalizingBlock 82 | sha 83 | 84 | jjw57/tev/xpn9vXTJevn8e/5wU= 85 | 86 | 87 | 88 | name 89 | __NSAutoBlock__ 90 | sha 91 | 92 | sX6EDSOPeVb/kkB2sGuBdpYPwQo= 93 | 94 | 95 | 96 | name 97 | _CTNativeGlyphStorage 98 | sha 99 | 100 | Tqpn+KXIPhk/wAlZeVGgjuv7dyY= 101 | 102 | 103 | 104 | """ 105 | 106 | MacPlist = """ 107 | 108 | 109 | 110 | 111 | name 112 | NSWindow 113 | sha 114 | 115 | SFeMN8U0BSGJXEsVB5y4/3tu8a4= 116 | 117 | 118 | 119 | name 120 | NSDrawerWindow 121 | sha 122 | 123 | /NgSMV9gYZR7dN7V+TRqUf8W7x4= 124 | 125 | 126 | 127 | name 128 | NSNavAdvancedSearchController 129 | sha 130 | 131 | TbJhqXch7kQchtzNaHxvbfKT7R4= 132 | 133 | 134 | 135 | name 136 | NSFindPanel 137 | sha 138 | 139 | zYGpaERs/FtA/hC0w04Z/VdobMs= 140 | 141 | 142 | 143 | name 144 | NSCarbonWindow 145 | sha 146 | 147 | ahavRAEYXohNEBwmK/fK9AkLJI4= 148 | 149 | 150 | 151 | name 152 | NSSecureTextView 153 | sha 154 | 155 | LbaEa2rmSFa0uK4Jj4jUn3GNK/Q= 156 | 157 | 158 | 159 | name 160 | __NSAutoBlock 161 | sha 162 | 163 | lyAIsod346R+vjRvhCmmISp/zA4= 164 | 165 | 166 | 167 | name 168 | NSViewHierarchyLock 169 | sha 170 | 171 | CIJQZlV2mLW4ViDWHAdVTjLgsTM= 172 | 173 | 174 | 175 | name 176 | NSBlock 177 | sha 178 | 179 | BQpaL8Om1fvPzIXyL+oW67/PnlI= 180 | 181 | 182 | 183 | name 184 | NSFontPanel 185 | sha 186 | 187 | vqtJfV9j/tynQ0OtJIBs6zYE0ps= 188 | 189 | 190 | 191 | name 192 | __NSStackBlock 193 | sha 194 | 195 | zRs7gD8UnN6tGEvpRLoBXwiY1ow= 196 | 197 | 198 | 199 | name 200 | NSFindPatternFieldEditor 201 | sha 202 | 203 | rXX5qhv5U5M14xaY/H7l7JvKZO8= 204 | 205 | 206 | 207 | name 208 | _PFManagedObjectReferenceQueue 209 | sha 210 | 211 | UrTPGUe41WVWdcBG1Dya8iEvxco= 212 | 213 | 214 | 215 | name 216 | __NSFinalizingBlock 217 | sha 218 | 219 | jjw57/tev/xpn9vXTJevn8e/5wU= 220 | 221 | 222 | 223 | name 224 | NSTableOptionsPanel 225 | sha 226 | 227 | Qm66oEUVhjdLMEgOe68K0nVDEPs= 228 | 229 | 230 | 231 | name 232 | NSColorPopoverController 233 | sha 234 | 235 | VKRPkoniO0lucOF1kHm7U19PzD4= 236 | 237 | 238 | 239 | name 240 | NSLazyBrowserCell 241 | sha 242 | 243 | /9eaS5QRt7u4JU00YIBG3DqV7eM= 244 | 245 | 246 | 247 | name 248 | NSTableOptions 249 | sha 250 | 251 | CRF7IZAowDmQm8WpD68IQ565ncM= 252 | 253 | 254 | 255 | name 256 | NSStringDrawingTextStorage 257 | sha 258 | 259 | SgzNnuoeiuoPAPPnM7FvW0JVVUU= 260 | 261 | 262 | 263 | name 264 | _NSFullScreenWindow 265 | sha 266 | 267 | gxE/KY51+hnKgl8M5kBgmaXMsNU= 268 | 269 | 270 | 271 | name 272 | _NSMagnifierWindow 273 | sha 274 | 275 | 6FjBniKPQyf85Jf7Jusye6+DwYk= 276 | 277 | 278 | 279 | name 280 | _NSCachedAttributedString 281 | sha 282 | 283 | q+3V5uisAQ0gV39x/RjMaXIKHUI= 284 | 285 | 286 | 287 | name 288 | _NSNonretainedFullScreenWindow 289 | sha 290 | 291 | puhB56xY9iFkgq2oZRpUWIzTVKA= 292 | 293 | 294 | 295 | name 296 | NSSubTextStorage 297 | sha 298 | 299 | b8VsLCw34olyVrN9ti1nTNBfVcE= 300 | 301 | 302 | 303 | name 304 | NSCorrectionSubPanel 305 | sha 306 | 307 | GkQ7kZTSNF5KGNlxFyzE+lpxTLU= 308 | 309 | 310 | 311 | name 312 | NSToolTipPanel 313 | sha 314 | 315 | lp+Z+UkqDP4ITu3UK2k57xK6GAI= 316 | 317 | 318 | 319 | name 320 | NSTokenTextView 321 | sha 322 | 323 | Ttf83RkW7X6eg44lXKbmDuE2w7E= 324 | 325 | 326 | 327 | name 328 | NSTextTab 329 | sha 330 | 331 | f7VofsahuBSzG9Lszpk+A3IdF84= 332 | 333 | 334 | 335 | name 336 | NSAccessoryWindow 337 | sha 338 | 339 | Q6z7uarex+PgkTJgrf7SRP51vGs= 340 | 341 | 342 | 343 | name 344 | NSCorrectionPanel 345 | sha 346 | 347 | HJDf026wh9bEpDPZn/neafSAffQ= 348 | 349 | 350 | 351 | name 352 | NSFontManager 353 | sha 354 | 355 | 3ZSbDioAG3dNHOYikR0AxPJRqnc= 356 | 357 | 358 | 359 | name 360 | NSPrintPreviewController 361 | sha 362 | 363 | anKU3rnEk4bMiB4Di39yfFGW+7o= 364 | 365 | 366 | 367 | name 368 | NSISObjectiveVariable 369 | sha 370 | 371 | Bw9S7Pex5Sp8OdRhF3Ymjnpcj7I= 372 | 373 | 374 | 375 | name 376 | NSPort 377 | sha 378 | 379 | We3vJYzFNeejp1rM03UIQ7IK7rI= 380 | 381 | 382 | 383 | name 384 | NSMachPort 385 | sha 386 | 387 | sEAJodm0DwS2BNbVe53fngii5Lc= 388 | 389 | 390 | 391 | name 392 | NSParagraphStyle 393 | sha 394 | 395 | dvUt4yMQmGGsWZlZ2j2NpgpnN8A= 396 | 397 | 398 | 399 | name 400 | NSMutableParagraphStyle 401 | sha 402 | 403 | +iyzpRrhoAOUQuJsqqH4I7ISjv0= 404 | 405 | 406 | 407 | name 408 | NSMessagePort 409 | sha 410 | 411 | VHdluyievZ9dDDlwW+dlzDzMSgY= 412 | 413 | 414 | 415 | name 416 | NSExceptionAlertController 417 | sha 418 | 419 | lR/CLWuBi8ZtYomSaF9LVHS8G0M= 420 | 421 | 422 | 423 | name 424 | NSISNonNegativeVariableWithDelegate 425 | sha 426 | 427 | GtoRBKxZzliZCAWux59ffB6r8xI= 428 | 429 | 430 | 431 | name 432 | NSFont 433 | sha 434 | 435 | 2xon5Aci9SfDzcgrtiwlQPlGpHM= 436 | 437 | 438 | 439 | name 440 | NSNavNewFolderController 441 | sha 442 | 443 | +YmCkaf8Q+4bA+/MSAgRUZty6RQ= 444 | 445 | 446 | 447 | name 448 | NSNavProgressErrorViewController 449 | sha 450 | 451 | v4NLJvLDJMVkXUyWhu1CHIMFNIw= 452 | 453 | 454 | 455 | name 456 | _NSBorderlessLayerTreeProjectionWindow 457 | sha 458 | 459 | vmYan5nzSrmnsAatwYHf4h4Bi/Q= 460 | 461 | 462 | 463 | name 464 | NSManagedObjectID 465 | sha 466 | 467 | KwHd7qY430VSAaMzGCouFwWWgUo= 468 | 469 | 470 | 471 | name 472 | NSSavePanel 473 | sha 474 | 475 | 8aVWn479HMFaFcUCDVa0G3AQ3wo= 476 | 477 | 478 | 479 | name 480 | NSISNonNegativeVariableWithDelegateToBeMinimized 481 | sha 482 | 483 | kSnm/5yoG3gzXvXW9vM0qSdo3Eg= 484 | 485 | 486 | 487 | name 488 | NSStatusBarWindow 489 | sha 490 | 491 | aDpl8bpqf6f7EuQfUyWtdIgNczA= 492 | 493 | 494 | 495 | name 496 | _NSSlideAndCrossFadeAnimationProjectionWindow 497 | sha 498 | 499 | N29wQ0c/FJv4HlfLQNZU1NFvxl4= 500 | 501 | 502 | 503 | name 504 | NSPanel 505 | sha 506 | 507 | nbOBxM5LSG2AavThMdqNx4OrxaE= 508 | 509 | 510 | 511 | name 512 | __NSSharedFontInstanceInfo 513 | sha 514 | 515 | Hfw+cCmab76aPudWHmQT6Wr9yc0= 516 | 517 | 518 | 519 | name 520 | _NSDuplicateDocumentAnimationProjectionWindow 521 | sha 522 | 523 | k2sV+fK5+4ZCsp12qpo+r0c7S5c= 524 | 525 | 526 | 527 | name 528 | _NSSavePanelTextView 529 | sha 530 | 531 | X8BeiDqxkZz5nRn+eamPekIDfHI= 532 | 533 | 534 | 535 | name 536 | NSISNonNegativeMarkerVariableToBeMinimized 537 | sha 538 | 539 | 87iKzyPmaeh2Qp2xSgKxn4SkOT4= 540 | 541 | 542 | 543 | name 544 | NSBrowserColumnViewController 545 | sha 546 | 547 | 3l09TtZ6XGvnSkwKv75f30g0gOg= 548 | 549 | 550 | 551 | name 552 | NSExternalRefCountedData 553 | sha 554 | 555 | tGkj/ekPJBm3p5Lh7RvRoK5khYc= 556 | 557 | 558 | 559 | name 560 | NSISNonNegativeVariableToBeMinimized 561 | sha 562 | 563 | BYOuxVYFzrPVGOkwt3D0eMmv3VQ= 564 | 565 | 566 | 567 | name 568 | NSISPureMarkerVariable 569 | sha 570 | 571 | 8s5xPyEDG1dlM7/nI02Zghu59jQ= 572 | 573 | 574 | 575 | name 576 | NSNavProgressStatusViewController 577 | sha 578 | 579 | fXYY9mdJ8CfQMRTzzk1ulSaVobk= 580 | 581 | 582 | 583 | name 584 | NSDockMiniViewWindow 585 | sha 586 | 587 | 3ZeRBWfU7XCsylSRUpqDl9InMkU= 588 | 589 | 590 | 591 | name 592 | NSISNonNegativeVariable 593 | sha 594 | 595 | 2QkSOU2kA4sCE0rGWNWeUErwAjY= 596 | 597 | 598 | 599 | name 600 | __NSFontTypefaceInfo 601 | sha 602 | 603 | M0YWTuFHGjKCbq5h7fgOJ6h22gg= 604 | 605 | 606 | 607 | name 608 | NSCarbonMenuWindow 609 | sha 610 | 611 | iegw7vmHI9dVQXH+vWpqCfioqbA= 612 | 613 | 614 | 615 | name 616 | _NSTextFinderOverlayWindow 617 | sha 618 | 619 | wy4SWbpy11FAc+Ph+x6XsMXB5Os= 620 | 621 | 622 | 623 | name 624 | NSSpellingPanel 625 | sha 626 | 627 | IEXWZk7TRqIxvNSRu8Z/r5oW81U= 628 | 629 | 630 | 631 | name 632 | NSISVariable 633 | sha 634 | 635 | PYR5FhTbcicFsSuM7fsf5mWbozI= 636 | 637 | 638 | 639 | name 640 | NSATSGlyphStorage 641 | sha 642 | 643 | B0BGyq1tzEkmPIG4C+chzCjPwyQ= 644 | 645 | 646 | 647 | name 648 | NSText 649 | sha 650 | 651 | wZS0fLqk9TpDBqOEZOv34OC2mFU= 652 | 653 | 654 | 655 | name 656 | NSNavFilepathInputController 657 | sha 658 | 659 | OGBcP6MLw40+BzMeVPPtiCkOr8M= 660 | 661 | 662 | 663 | name 664 | NSNavProgressWindow 665 | sha 666 | 667 | /NR/6hsRv+uSVyNwCRKJr4Si3zE= 668 | 669 | 670 | 671 | name 672 | NSISNonNegativeMarkerVariable 673 | sha 674 | 675 | hF1GmfJvPnDQBwQyaIJdrdtdlok= 676 | 677 | 678 | 679 | name 680 | __NSOperationInternal 681 | sha 682 | 683 | ROSeGwWpNKnZxacFFj1PFUGoRSQ= 684 | 685 | 686 | 687 | name 688 | NSSingleLineTypesetter 689 | sha 690 | 691 | mEoN+Xv4IBzGQEMGB2wU1yUhJbc= 692 | 693 | 694 | 695 | name 696 | NSISVariableWithDelegate 697 | sha 698 | 699 | JJc4QSvnGGdiBd3fwVdZScQWMpQ= 700 | 701 | 702 | 703 | name 704 | NSNavProgressWindowController 705 | sha 706 | 707 | qpt1Mw+o+tqNStZMQxJHTRCywKA= 708 | 709 | 710 | 711 | name 712 | _NSBrowserTableColumnViewController 713 | sha 714 | 715 | H/UmwkD3kRafI04jpP3P4LcSvgU= 716 | 717 | 718 | 719 | name 720 | NSImage 721 | sha 722 | 723 | 98w7UxBrKaYsvbQzj6JGUJ+X5nc= 724 | 725 | 726 | 727 | name 728 | NSATSTypesetter 729 | sha 730 | 731 | 6i+fLL9rpyN+ZHDMdZypvXAs0WY= 732 | 733 | 734 | 735 | name 736 | _NSPopoverWindow 737 | sha 738 | 739 | 7NDJV6/O/hXno6ss2nKurRdFhrE= 740 | 741 | 742 | 743 | name 744 | NSRulerMarkerPanel 745 | sha 746 | 747 | Z66vWYyjSvjpCuh8GEgANLxKaUA= 748 | 749 | 750 | 751 | name 752 | _NSCoreManagedObjectID 753 | sha 754 | 755 | ULIuKpe0CGGpUXIgdL+F5FSzGiQ= 756 | 757 | 758 | 759 | name 760 | __NSFinalizingBlock__ 761 | sha 762 | 763 | 3AZZFtRa6m+OCKyJrAtzLGJn/wA= 764 | 765 | 766 | 767 | name 768 | _NSBrowserPreviewColumnViewController 769 | sha 770 | 771 | W4odqX5yXXCBzwzguHOPXIXWoeE= 772 | 773 | 774 | 775 | name 776 | __NSATSStringSegment 777 | sha 778 | 779 | bzQVPTMn4pgVaw3FsAmOiyJAiJw= 780 | 781 | 782 | 783 | name 784 | _NSBrowserMatrixColumnViewController 785 | sha 786 | 787 | Ohkhh6cAV7VU31NQV+eI9oU9XnM= 788 | 789 | 790 | 791 | name 792 | NSPersistentUIWindowInfo 793 | sha 794 | 795 | 5fBFUxrIXWvsMyb2QL5JGKvRHag= 796 | 797 | 798 | 799 | name 800 | _NSAutomaticFocusRingOverlayWindow 801 | sha 802 | 803 | qS/ZwOqufQPYXr5n7l+wYNBXelw= 804 | 805 | 806 | 807 | name 808 | NSPersistentUIEncodedReference 809 | sha 810 | 811 | 3BCrWRJDZBJ54IKz+c079E17lCU= 812 | 813 | 814 | 815 | name 816 | __NSAutoBlock__ 817 | sha 818 | 819 | sX6EDSOPeVb/kkB2sGuBdpYPwQo= 820 | 821 | 822 | 823 | name 824 | NSLineFragmentRenderingContext 825 | sha 826 | 827 | rGK8uSbdJD0/xCZHUMa7a1aTFiw= 828 | 829 | 830 | 831 | name 832 | NSComboBoxWindow 833 | sha 834 | 835 | oGMLwra+9sOGRwcO2O//kuUx6QA= 836 | 837 | 838 | 839 | name 840 | NSProgressPanel 841 | sha 842 | 843 | U03ljaFAy3oaJ9OJJDna0UYc8IQ= 844 | 845 | 846 | 847 | name 848 | _NSFlippedImage 849 | sha 850 | 851 | vHs+POfjFBtGd0TbQ8OkuTFmCMc= 852 | 853 | 854 | 855 | name 856 | NSOpenPanel 857 | sha 858 | 859 | 8+tajnD2v0E3iS6US5QjfTRsRrQ= 860 | 861 | 862 | 863 | name 864 | _NSOrderOutAnimationProxyWindow 865 | sha 866 | 867 | d+DVB4OnLn66rGqql0dPtCbo1co= 868 | 869 | 870 | 871 | name 872 | NSScalarObjectID64 873 | sha 874 | 875 | mN/zOpK3GneP90WS0CIYsMzFT5Y= 876 | 877 | 878 | 879 | name 880 | _NSFullScreenUnbufferedWindow 881 | sha 882 | 883 | NcJeItBLWUr+x7IMtY0HS+5KNVI= 884 | 885 | 886 | 887 | name 888 | NSTableCellView 889 | sha 890 | 891 | A1uBQqIOINc58aSoIYYd3KXvCTQ= 892 | 893 | 894 | 895 | name 896 | NSBasicObjectID 897 | sha 898 | 899 | XyJyWRP4cds6vqAbr+12C5rzXtg= 900 | 901 | 902 | 903 | name 904 | __NSStackBlock__ 905 | sha 906 | 907 | 3papHp41j4ZHdNNrNkFTcEBSr8s= 908 | 909 | 910 | 911 | name 912 | NSTextViewCompletionWindow 913 | sha 914 | 915 | co0ndJdiBotr7JJRSr1DyKpsWAk= 916 | 917 | 918 | 919 | name 920 | NSScalarObjectID48 921 | sha 922 | 923 | 6IwZlZkW4FMH/eDeHEVEL6Ov7pA= 924 | 925 | 926 | 927 | name 928 | NSTypeSelectPanel 929 | sha 930 | 931 | 5k9PqB+GISss6qvE1SFmTNhboJM= 932 | 933 | 934 | 935 | name 936 | NSDocumentRevisionsTimelineWindow 937 | sha 938 | 939 | Sj7E61aLBYq7vqDbWNJbme8MNsA= 940 | 941 | 942 | 943 | name 944 | _NSScalarObjectID 945 | sha 946 | 947 | EaNh4n2xPuTh0XoNxHRSdrC1frM= 948 | 949 | 950 | 951 | name 952 | NSNavNodeSharedServerController 953 | sha 954 | 955 | N3Kbz1/PiHVyjvFs5chixV/izVw= 956 | 957 | 958 | 959 | name 960 | NSCollectionViewItem 961 | sha 962 | 963 | mLK2tFhdKjwMyCfnbmMHflOyUFk= 964 | 965 | 966 | 967 | name 968 | NSNavNodePreviewController 969 | sha 970 | 971 | 6caXQIAux9K9ydl7IXQjQw/hWnE= 972 | 973 | 974 | 975 | name 976 | _NSQuickLookWrapperDocumentWindow 977 | sha 978 | 979 | D31WdK2TSOK9K1y09vjS/EfA9Lk= 980 | 981 | 982 | 983 | name 984 | NSColorSpace 985 | sha 986 | 987 | lcprGOTF+DWuLMEs3M3sTsp2lAY= 988 | 989 | 990 | 991 | name 992 | NSPrintPanelOldAccessoryController 993 | sha 994 | 995 | fN11drCx/Ms+11Hj9JN41SfCTMQ= 996 | 997 | 998 | 999 | name 1000 | _PFTask 1001 | sha 1002 | 1003 | dUvjXLAgFMqMYWDceu4PiBmfp2g= 1004 | 1005 | 1006 | 1007 | name 1008 | NSWindowController 1009 | sha 1010 | 1011 | fxg65zpHoYZciz2tdOd7o3HOtu0= 1012 | 1013 | 1014 | 1015 | name 1016 | NSAttributeDictionary 1017 | sha 1018 | 1019 | OikvRNnrgR6JITga0Tb1G7EP4qU= 1020 | 1021 | 1022 | 1023 | name 1024 | NSSidebarImage 1025 | sha 1026 | 1027 | mlem51SivOYgKEJgkwMUnd/b2k8= 1028 | 1029 | 1030 | 1031 | name 1032 | NSViewController 1033 | sha 1034 | 1035 | ooON0P+jNonvYry11rt6S/b2sfs= 1036 | 1037 | 1038 | 1039 | name 1040 | NSDocumentRevisionsWindow 1041 | sha 1042 | 1043 | 0lNAsunn2KqpjFmZAQkrqVqMBKQ= 1044 | 1045 | 1046 | 1047 | name 1048 | _NSToolbarDefaultImageRepWindow 1049 | sha 1050 | 1051 | 8fXzOOF3REOIBDYCOPz8+6gXTA4= 1052 | 1053 | 1054 | 1055 | name 1056 | NSNavPreviewController 1057 | sha 1058 | 1059 | 4b+uu16zT6HmTrDXeJa6mVHGFL4= 1060 | 1061 | 1062 | 1063 | name 1064 | NSTempAttributeDictionary 1065 | sha 1066 | 1067 | 82aVtqcnZnAvxUo45js0DVQhh44= 1068 | 1069 | 1070 | 1071 | name 1072 | NSNavSharedServerController 1073 | sha 1074 | 1075 | RbjLn+o68uMwnVPFNpVKaVXqhe4= 1076 | 1077 | 1078 | 1079 | name 1080 | _NSFullScreenTransitionOverlayWindow 1081 | sha 1082 | 1083 | c7HGS1SwVkIm0Az0KCMSN620faw= 1084 | 1085 | 1086 | 1087 | name 1088 | NSTextView 1089 | sha 1090 | 1091 | bgdKj9Wtpr9iFUmamPuebJopXkU= 1092 | 1093 | 1094 | 1095 | name 1096 | PBOXMenuWindow 1097 | sha 1098 | 1099 | rg0DJXYfH0VYJbiPqDdy/fW38YU= 1100 | 1101 | 1102 | 1103 | name 1104 | NSToolbarConfigPanel 1105 | sha 1106 | 1107 | HzqAu6fBQcmlh0Zs6FMPMSzkgu0= 1108 | 1109 | 1110 | 1111 | name 1112 | NSLocalWindowWrappingRemoteWindow 1113 | sha 1114 | 1115 | TJZzArlE4x8Lr6u68BwcEgC3hr8= 1116 | 1117 | 1118 | 1119 | name 1120 | NSToolbarFullScreenWindow 1121 | sha 1122 | 1123 | aSDvp1iijMMgobjNdUZA/AWuYQo= 1124 | 1125 | 1126 | 1127 | """ 1128 | 1129 | 1130 | import plistlib 1131 | 1132 | iOSPlist = plistlib.readPlistFromString(iOSPlist) 1133 | MacPlist = plistlib.readPlistFromString(MacPlist) 1134 | 1135 | 1136 | def PrintArray(hashesToNames, indent): 1137 | indentStr = ' ' * indent * 4 1138 | for byte in range(256): 1139 | matching = [x for x in hashesToNames.keys() if x.startswith(chr(byte))] 1140 | if matching: 1141 | d = {} 1142 | for hash in matching: 1143 | if len(hash) > 1: 1144 | d[hash[1:]] = hashesToNames[hash] 1145 | if len(d) > 1: 1146 | print '%s[0x%x] = { 1, (struct _NativeZWRTableEntry[256]) { // %d' % (indentStr, byte, indent) 1147 | PrintArray(d, indent + 1) 1148 | print indentStr + '}},' 1149 | elif d: 1150 | hash = d.keys()[0] 1151 | hashBytes = ['0x%x' % ord(x) for x in hash] 1152 | hashC = ', '.join(hashBytes) 1153 | print '%s[0x%x] = { 0, (unsigned char[]){ %s } }, // %s' % (indentStr, byte, hashC, d[hash]) 1154 | else: 1155 | for hash in matching: 1156 | print '%s[0x%x] = { 0, &_MAZeroingWeakRefClassPresentToken }, // %s' % (indentStr, byte, hashesToNames[hash]) 1157 | 1158 | 1159 | 1160 | hashesToNames = {} 1161 | for x in iOSPlist + MacPlist: 1162 | hashesToNames[x['sha'].data] = x['name'] 1163 | 1164 | print 'static void *_MAZeroingWeakRefClassPresentToken = &_MAZeroingWeakRefClassPresentToken;' 1165 | print 'struct _NativeZWRTableEntry { BOOL isTable; void *ptr; };' 1166 | print 'static struct _NativeZWRTableEntry _MAZeroingWeakRefClassNativeWeakReferenceNotAllowedTable[256] = {' 1167 | PrintArray(hashesToNames, 1) 1168 | print '};' 1169 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | MAZeroingWeakRef - by Mike Ash - mike@mikeash.com 2 | 3 | Introduction 4 | ------------ 5 | 6 | MAZeroingWeakRef is a library for using zeroing weak references in retain/release Cocoa and Cocoa Touch code. These are references which do not keep an object alive, and which automatically become nil once the object is destroyed. 7 | 8 | MAZeroingWeakRef does not work under Cocoa garbage collection. The built-in __weak specifier exists for that, although it is used somewhat differently. 9 | 10 | The API is simple and mostly self-explanatory from the header file. Note that cleanup blocks are only needed for advanced uses when you need to take more action than simply zeroing the reference when the target object is destroyed. Be sure to heed the warning in the header about not doing too much work in the cleanup block. 11 | 12 | In order to allow weak references to CoreFoundation bridged objects, a fair amount of crazy hacking of private APIs had to be done. For people who don't like that sort of thing, or who are worried about rejection when building for iOS, this crazy hacking can be reduced or disabled altogether. Look at the COREFOUNDATION_HACK_LEVEL macro in MAZeroingWeakRef.m, and the comment above it which explains what the different levels do. 13 | 14 | A similar KVO_HACK_LEVEL macro is also available. 15 | 16 | App Store 17 | --------- 18 | 19 | For iOS work, or Mac App Store work, you will probably want to set both COREFOUNDATION_HACK_LEVEL and KVO_HACK_LEVEL to `0`. In this mode, MAZeroingWeakRef uses no private APIs. 20 | 21 | Also, if you need your app to run on iOS 3.x you need to disable blocks based code setting USE_BLOCKS_BASED_LOCKING to `0`. 22 | 23 | Source Code 24 | ----------- 25 | 26 | The MAZeroingWeakRef code is available from GitHub: 27 | 28 | http://github.com/mikeash/MAZeroingWeakRef 29 | 30 | MAZeroingWeakRef is made available under a BSD license. 31 | 32 | More Information 33 | ---------------- 34 | 35 | For more information about it, this blog post gives a basic introduction to the API: 36 | 37 | http://mikeash.com/pyblog/introducing-mazeroingweakref.html 38 | 39 | This describes how it works in most cases: 40 | 41 | http://mikeash.com/pyblog/friday-qa-2010-07-16-zeroing-weak-references-in-objective-c.html 42 | 43 | And this describes some of the more hairy parts: 44 | 45 | http://mikeash.com/pyblog/friday-qa-2010-07-30-zeroing-weak-references-to-corefoundation-objects.html 46 | 47 | Enjoy! 48 | -------------------------------------------------------------------------------- /Source/MANotificationCenterAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // MANotificationCenterAdditions.h 3 | // ZeroingWeakRef 4 | // 5 | // Created by Michael Ash on 7/12/10. 6 | // 7 | 8 | #import 9 | 10 | 11 | @interface NSNotificationCenter (MAZeroingWeakRefAdditions) 12 | 13 | /** 14 | * Returns an opaque observation handle that can be removed with NSNotificationCenter's 'removeObserver:'. 15 | */ 16 | - (id)addWeakObserver: (id)observer selector: (SEL)selector name: (NSString *)name object: (id)object; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Source/MANotificationCenterAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // MANotificationCenterAdditions.m 3 | // ZeroingWeakRef 4 | // 5 | // Created by Michael Ash on 7/12/10. 6 | // 7 | 8 | #import "MANotificationCenterAdditions.h" 9 | 10 | #import "MAZeroingWeakRef.h" 11 | 12 | 13 | @implementation NSNotificationCenter (MAZeroingWeakRefAdditions) 14 | 15 | - (id)addWeakObserver: (id)observer selector: (SEL)selector name: (NSString *)name object: (id)object 16 | { 17 | MAZeroingWeakRef *ref = [[MAZeroingWeakRef alloc] initWithTarget: observer]; 18 | 19 | id noteObj = [self addObserverForName: name object:object queue: nil usingBlock: ^(NSNotification *note) { 20 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 21 | 22 | id observer = [ref target]; 23 | [observer performSelector: selector withObject: note]; 24 | 25 | [pool release]; 26 | }]; 27 | 28 | [ref setCleanupBlock: ^(id target) { 29 | [self removeObserver: noteObj]; 30 | [ref autorelease]; 31 | }]; 32 | 33 | return noteObj; 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Source/MAWeakArray.h: -------------------------------------------------------------------------------- 1 | // 2 | // MAWeakArray.h 3 | // ZeroingWeakRef 4 | // 5 | // Created by Mike Ash on 7/13/10. 6 | // 7 | 8 | #import 9 | 10 | 11 | @interface MAWeakArray : NSMutableArray 12 | { 13 | NSMutableArray *_weakRefs; 14 | } 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Source/MAWeakArray.m: -------------------------------------------------------------------------------- 1 | // 2 | // MAWeakArray.m 3 | // ZeroingWeakRef 4 | // 5 | // Created by Mike Ash on 7/13/10. 6 | // 7 | 8 | #import "MAWeakArray.h" 9 | 10 | #import "MAZeroingWeakRef.h" 11 | 12 | 13 | @implementation MAWeakArray 14 | 15 | - (id)init 16 | { 17 | return [self initWithCapacity:0]; 18 | } 19 | 20 | - (id)initWithCapacity:(NSUInteger)numItems 21 | { 22 | if((self = [super init])) 23 | { 24 | _weakRefs = [[NSMutableArray alloc] initWithCapacity:numItems]; 25 | } 26 | return self; 27 | } 28 | 29 | - (id)initWithObjects:(const id [])objects count:(NSUInteger)cnt 30 | { 31 | self = [self initWithCapacity:cnt]; 32 | 33 | for(NSInteger i = 0; i < cnt; i++) 34 | if(objects[i] != nil) 35 | [self addObject:objects[i]]; 36 | 37 | return self; 38 | } 39 | 40 | - (void)dealloc 41 | { 42 | [_weakRefs release]; 43 | [super dealloc]; 44 | } 45 | 46 | - (NSUInteger)count 47 | { 48 | return [_weakRefs count]; 49 | } 50 | 51 | - (id)objectAtIndex: (NSUInteger)index 52 | { 53 | return [[_weakRefs objectAtIndex: index] target]; 54 | } 55 | 56 | - (void)addObject: (id)anObject 57 | { 58 | [_weakRefs addObject: [MAZeroingWeakRef refWithTarget: anObject]]; 59 | } 60 | 61 | - (void)insertObject: (id)anObject atIndex: (NSUInteger)index 62 | { 63 | [_weakRefs insertObject: [MAZeroingWeakRef refWithTarget: anObject] 64 | atIndex: index]; 65 | } 66 | 67 | - (void)removeLastObject 68 | { 69 | [_weakRefs removeLastObject]; 70 | } 71 | 72 | - (void)removeObjectAtIndex: (NSUInteger)index 73 | { 74 | [_weakRefs removeObjectAtIndex: index]; 75 | } 76 | 77 | - (void)replaceObjectAtIndex: (NSUInteger)index withObject: (id)anObject 78 | { 79 | [_weakRefs replaceObjectAtIndex: index 80 | withObject: [MAZeroingWeakRef refWithTarget: anObject]]; 81 | } 82 | 83 | - (id)copyWithZone:(NSZone *)zone 84 | { 85 | id *objects = calloc([self count], sizeof(id)); 86 | NSInteger count = 0; 87 | 88 | for(id obj in self) 89 | if(obj != nil) 90 | { 91 | objects[count] = obj; 92 | count++; 93 | } 94 | 95 | NSArray *ret = [[NSArray alloc] initWithObjects:objects count:count]; 96 | 97 | free(objects); 98 | 99 | return ret; 100 | } 101 | 102 | - (id)mutableCopyWithZone:(NSZone *)zone 103 | { 104 | id *objects = calloc([self count], sizeof(id)); 105 | NSInteger count = 0; 106 | 107 | for(id obj in self) 108 | if(obj != nil) 109 | { 110 | objects[count] = obj; 111 | count++; 112 | } 113 | 114 | NSArray *ret = [[NSMutableArray alloc] initWithObjects:objects count:count]; 115 | 116 | free(objects); 117 | 118 | return ret; 119 | } 120 | 121 | @end 122 | -------------------------------------------------------------------------------- /Source/MAWeakDictionary.h: -------------------------------------------------------------------------------- 1 | // 2 | // MAWeakDictionary.h 3 | // ZeroingWeakRef 4 | // 5 | // Created by Mike Ash on 7/13/10. 6 | // 7 | 8 | #import 9 | 10 | 11 | @interface MAWeakDictionary : NSMutableDictionary 12 | { 13 | NSMutableDictionary *_dict; 14 | } 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Source/MAWeakDictionary.m: -------------------------------------------------------------------------------- 1 | // 2 | // MAWeakDictionary.m 3 | // ZeroingWeakRef 4 | // 5 | // Created by Mike Ash on 7/13/10. 6 | // 7 | 8 | #import "MAWeakDictionary.h" 9 | 10 | #import "MAZeroingWeakRef.h" 11 | 12 | 13 | @implementation MAWeakDictionary 14 | 15 | - (id)init 16 | { 17 | if((self = [super init])) 18 | { 19 | _dict = [[NSMutableDictionary alloc] init]; 20 | } 21 | return self; 22 | } 23 | 24 | - (void)dealloc 25 | { 26 | [_dict release]; 27 | [super dealloc]; 28 | } 29 | 30 | - (NSUInteger)count 31 | { 32 | return [_dict count]; 33 | } 34 | 35 | - (id)objectForKey: (id)aKey 36 | { 37 | MAZeroingWeakRef *ref = [_dict objectForKey: aKey]; 38 | id obj = [ref target]; 39 | 40 | // clean out keys whose objects have gone away 41 | if(ref && !obj) 42 | [_dict removeObjectForKey: aKey]; 43 | 44 | return obj; 45 | } 46 | 47 | - (NSEnumerator *)keyEnumerator 48 | { 49 | // enumerate over a copy because -objectForKey: mutates 50 | // which could cause an exception in code that should 51 | // appear to be correct 52 | return [[_dict allKeys] objectEnumerator]; 53 | } 54 | 55 | - (void)removeObjectForKey: (id)aKey 56 | { 57 | [_dict removeObjectForKey: aKey]; 58 | } 59 | 60 | - (void)setObject: (id)anObject forKey: (id)aKey 61 | { 62 | [_dict setObject: [MAZeroingWeakRef refWithTarget: anObject] 63 | forKey: aKey]; 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /Source/MAZeroingWeakProxy.h: -------------------------------------------------------------------------------- 1 | // 2 | // MAZeroingWeakProxy.h 3 | // ZeroingWeakRef 4 | // 5 | // Created by Michael Ash on 7/17/10. 6 | // Copyright 2010 Michael Ash. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @class MAZeroingWeakRef; 13 | 14 | @interface MAZeroingWeakProxy : NSProxy 15 | { 16 | MAZeroingWeakRef *_weakRef; 17 | Class _targetClass; 18 | } 19 | 20 | + (id)proxyWithTarget: (id)target; 21 | 22 | - (id)initWithTarget: (id)target; 23 | 24 | - (id)zeroingProxyTarget; 25 | 26 | #if NS_BLOCKS_AVAILABLE 27 | // same caveats/restrictions as MAZeroingWeakRef cleanup block 28 | - (void)setCleanupBlock: (void (^)(id target))block; 29 | #endif 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /Source/MAZeroingWeakProxy.m: -------------------------------------------------------------------------------- 1 | // 2 | // MAZeroingWeakProxy.m 3 | // ZeroingWeakRef 4 | // 5 | // Created by Michael Ash on 7/17/10. 6 | // Copyright 2010 Michael Ash. All rights reserved. 7 | // 8 | 9 | #import "MAZeroingWeakProxy.h" 10 | 11 | #import "MAZeroingWeakRef.h" 12 | 13 | @implementation MAZeroingWeakProxy 14 | 15 | + (id)proxyWithTarget: (id)target 16 | { 17 | return [[[self alloc] initWithTarget: target] autorelease]; 18 | } 19 | 20 | - (id)initWithTarget: (id)target 21 | { 22 | // stash the class of the target so we can get method signatures after it goes away 23 | _targetClass = [target class]; 24 | _weakRef = [[MAZeroingWeakRef alloc] initWithTarget: target]; 25 | return self; 26 | } 27 | 28 | - (void)dealloc 29 | { 30 | [_weakRef release]; 31 | [super dealloc]; 32 | } 33 | 34 | - (id)zeroingProxyTarget 35 | { 36 | return [_weakRef target]; 37 | } 38 | 39 | #if NS_BLOCKS_AVAILABLE 40 | - (void)setCleanupBlock: (void (^)(id target))block 41 | { 42 | [_weakRef setCleanupBlock: block]; 43 | } 44 | #endif 45 | 46 | - (id)forwardingTargetForSelector: (SEL)sel 47 | { 48 | return [_weakRef target]; 49 | } 50 | 51 | - (NSMethodSignature *)methodSignatureForSelector: (SEL)sel 52 | { 53 | return [_targetClass instanceMethodSignatureForSelector: sel]; 54 | } 55 | 56 | - (void)forwardInvocation: (NSInvocation *)inv 57 | { 58 | NSMethodSignature *sig = [inv methodSignature]; 59 | NSUInteger returnLength = [sig methodReturnLength]; 60 | 61 | if(returnLength) 62 | { 63 | char buf[returnLength]; 64 | bzero(buf, sizeof(buf)); 65 | [inv setReturnValue: buf]; 66 | } 67 | } 68 | 69 | - (BOOL)respondsToSelector: (SEL)sel 70 | { 71 | id target = [_weakRef target]; 72 | if(target) 73 | return [target respondsToSelector: sel]; 74 | else 75 | return [_targetClass instancesRespondToSelector: sel]; 76 | } 77 | 78 | - (BOOL)conformsToProtocol: (Protocol *)protocol 79 | { 80 | id target = [_weakRef target]; 81 | if(target) 82 | return [target conformsToProtocol: protocol]; 83 | else 84 | return [_targetClass conformsToProtocol: protocol]; 85 | } 86 | 87 | // NSProxy implements these for some incomprehensibly stupid reason 88 | 89 | - (NSUInteger)hash 90 | { 91 | return [[_weakRef target] hash]; 92 | } 93 | 94 | - (BOOL)isEqual: (id)obj 95 | { 96 | return [[_weakRef target] isEqual: obj]; 97 | } 98 | 99 | @end 100 | -------------------------------------------------------------------------------- /Source/MAZeroingWeakRef.h: -------------------------------------------------------------------------------- 1 | // 2 | // MAZeroingWeakRef.h 3 | // ZeroingWeakRef 4 | // 5 | // Created by Michael Ash on 7/5/10. 6 | // 7 | 8 | #import 9 | 10 | 11 | @interface MAZeroingWeakRef : NSObject 12 | { 13 | id _target; 14 | BOOL _nativeZWR; 15 | #if NS_BLOCKS_AVAILABLE 16 | void (^_cleanupBlock)(id target); 17 | #endif 18 | } 19 | 20 | + (BOOL)canRefCoreFoundationObjects; 21 | 22 | + (id)refWithTarget: (id)target; 23 | 24 | - (id)initWithTarget: (id)target; 25 | 26 | #if NS_BLOCKS_AVAILABLE 27 | // ON 10.7: 28 | // cleanup block runs while the target's memory is still 29 | // allocated but after all dealloc methods have run 30 | // (it runs at associated object cleanup time) 31 | // you can use the target's pointer value but don't 32 | // manipulate its contents! 33 | 34 | // ON 10.6 AND BELOW: 35 | // cleanup block runs while the global ZWR lock is held 36 | // so make it short and sweet! 37 | // use GCD or something to schedule execution later 38 | // if you need to do something that may take a while 39 | // 40 | // it is unsafe to call -target on the weak ref from 41 | // inside the cleanup block, which is why the target 42 | // is passed in as a parameter 43 | // note that you must not resurrect the target at this point! 44 | - (void)setCleanupBlock: (void (^)(id target))block; 45 | #endif 46 | 47 | - (id)target; 48 | 49 | @end 50 | 51 | #ifndef __has_feature 52 | #define __has_feature(feature) 0 53 | #endif 54 | 55 | #define MAWeakVar(var) __weak_ ## var 56 | 57 | #if __has_feature(objc_arc_weak) 58 | 59 | #define MAWeakDeclare(var) __weak __typeof__((var)) MAWeakVar(var) = var 60 | #define MAWeakImport(var) __typeof__((MAWeakVar(var))) var = MAWeakVar(var) 61 | #define MAWeakImportReturn(var) MAWeakImport(var); do { if(var == nil) return; } while(NO) 62 | 63 | #else 64 | 65 | #define MAWeakDeclare(var) __typeof__((var)) MAWeakVar(var) = (id)[MAZeroingWeakRef refWithTarget:var] 66 | #define MAWeakImport(var) __typeof__((MAWeakVar(var))) var = [(MAZeroingWeakRef *)MAWeakVar(var) target] 67 | #define MAWeakImportReturn(var) MAWeakImport(var); do { if(var == nil) return; } while(NO) 68 | 69 | #endif 70 | 71 | #define MAWeakSelfDeclare() MAWeakDeclare(self) 72 | #define MAWeakSelfImport() MAWeakImport(self) 73 | #define MAWeakSelfImportReturn() MAWeakImportReturn(self) 74 | -------------------------------------------------------------------------------- /Source/MAZeroingWeakRef.m: -------------------------------------------------------------------------------- 1 | // 2 | // MAZeroingWeakRef.m 3 | // ZeroingWeakRef 4 | // 5 | // Created by Michael Ash on 7/5/10. 6 | // 7 | 8 | #import "MAZeroingWeakRef.h" 9 | 10 | #import "MAZeroingWeakRefNativeZWRNotAllowedTable.h" 11 | 12 | #if __APPLE__ 13 | #import 14 | 15 | #import 16 | #import 17 | #import 18 | #import 19 | #import 20 | #import 21 | #else 22 | #import 23 | #endif 24 | 25 | 26 | /* 27 | The COREFOUNDATION_HACK_LEVEL macro allows you to control how much horrible CF 28 | hackery is enabled. The following levels are defined: 29 | 30 | 3 - Completely insane hackery allows weak references to CF objects, deallocates 31 | them asynchronously in another thread to eliminate resurrection-related race 32 | condition and crash. 33 | 34 | 2 - Full hackery allows weak references to CF objects by doing horrible 35 | things with the private CF class table. Extremely small risk of resurrection- 36 | related race condition leading to a crash. 37 | 38 | 1 - Mild hackery allows foolproof identification of CF objects and will assert 39 | if trying to make a ZWR to one. 40 | 41 | 0 - No hackery, checks for an "NSCF" prefix in the class name to identify CF 42 | objects and will assert if trying to make a ZWR to one 43 | */ 44 | #ifndef COREFOUNDATION_HACK_LEVEL 45 | #define COREFOUNDATION_HACK_LEVEL 0 46 | #endif 47 | 48 | /* 49 | The KVO_HACK_LEVEL macro allows similar control over the amount of KVO hackery. 50 | 51 | 1 - Use the private _isKVOA method to check for a KVO dynamic subclass. 52 | 53 | 0 - No hackery, uses the KVO overridden -class to check. 54 | */ 55 | #ifndef KVO_HACK_LEVEL 56 | #define KVO_HACK_LEVEL 0 57 | #endif 58 | 59 | /* 60 | The USE_BLOCKS_BASED_LOCKING macro allows control on the code structure used 61 | during lock checking. You want to disable blocks if you want your app to work 62 | on iOS 3.x devices. iOS 4.x and above can use blocks. 63 | 64 | 1 - Use blocks for lock checks. 65 | 66 | 0 - Don't use blocks for lock checks. 67 | */ 68 | #ifndef USE_BLOCKS_BASED_LOCKING 69 | #define USE_BLOCKS_BASED_LOCKING 1 70 | #endif 71 | 72 | #if KVO_HACK_LEVEL >= 1 73 | @interface NSObject (KVOPrivateMethod) 74 | 75 | - (BOOL)_isKVOA; 76 | 77 | @end 78 | #endif 79 | 80 | 81 | @interface NSObject (MAZeroingWeakRefSwizzled) 82 | - (void)MAZeroingWeakRef_KVO_original_release; 83 | - (void)MAZeroingWeakRef_KVO_original_dealloc; 84 | - (void)MAZeroingWeakRef_KVO_original_addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath context:(void *)context; 85 | - (void)MAZeroingWeakRef_KVO_original_removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath; 86 | - (void)MAZeroingWeakRef_KVO_original_removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath context:(void *)context; 87 | @end 88 | 89 | 90 | static void EnsureCustomSubclass(id obj); 91 | 92 | @interface MAZeroingWeakRef () 93 | 94 | - (void)_zeroTarget; 95 | - (void)_executeCleanupBlockWithTarget: (id)target; 96 | 97 | @end 98 | 99 | 100 | static id (*objc_loadWeak_fptr)(id *location); 101 | static id (*objc_storeWeak_fptr)(id *location, id obj); 102 | 103 | @interface _MAZeroingWeakRefCleanupHelper : NSObject 104 | { 105 | MAZeroingWeakRef *_ref; 106 | id _target; 107 | } 108 | 109 | - (id)initWithRef: (MAZeroingWeakRef *)ref target: (id)target; 110 | 111 | @end 112 | 113 | @implementation _MAZeroingWeakRefCleanupHelper 114 | 115 | - (id)initWithRef: (MAZeroingWeakRef *)ref target: (id)target 116 | { 117 | if((self = [self init])) 118 | { 119 | objc_storeWeak_fptr(&_ref, ref); 120 | _target = target; 121 | } 122 | return self; 123 | } 124 | 125 | - (void)dealloc 126 | { 127 | MAZeroingWeakRef *ref = objc_loadWeak_fptr(&_ref); 128 | [ref _executeCleanupBlockWithTarget: _target]; 129 | objc_storeWeak_fptr(&_ref, nil); 130 | 131 | [super dealloc]; 132 | } 133 | 134 | @end 135 | 136 | 137 | @implementation MAZeroingWeakRef 138 | 139 | #if COREFOUNDATION_HACK_LEVEL >= 2 140 | 141 | typedef struct __CFRuntimeClass { // Version 0 struct 142 | CFIndex version; 143 | const char *className; 144 | void (*init)(CFTypeRef cf); 145 | CFTypeRef (*copy)(CFAllocatorRef allocator, CFTypeRef cf); 146 | void (*finalize)(CFTypeRef cf); 147 | Boolean (*equal)(CFTypeRef cf1, CFTypeRef cf2); 148 | CFHashCode (*hash)(CFTypeRef cf); 149 | CFStringRef (*copyFormattingDesc)(CFTypeRef cf, CFDictionaryRef formatOptions); // str with retain 150 | CFStringRef (*copyDebugDesc)(CFTypeRef cf); // str with retain 151 | void (*reclaim)(CFTypeRef cf); 152 | } CFRuntimeClass; 153 | 154 | extern CFRuntimeClass * _CFRuntimeGetClassWithTypeID(CFTypeID typeID); 155 | 156 | typedef void (*CFFinalizeFptr)(CFTypeRef); 157 | static CFFinalizeFptr *gCFOriginalFinalizes; 158 | static size_t gCFOriginalFinalizesSize; 159 | 160 | #endif 161 | 162 | #if COREFOUNDATION_HACK_LEVEL >= 1 163 | 164 | extern Class *__CFRuntimeObjCClassTable; 165 | 166 | #endif 167 | 168 | static pthread_mutex_t gMutex; 169 | 170 | #if __APPLE__ 171 | static CFMutableDictionaryRef gObjectWeakRefsMap; // maps (non-retained) objects to CFMutableSetRefs containing weak refs 172 | #else 173 | static NSMapTable *gObjectWeakRefsMap; 174 | #endif 175 | 176 | static NSMutableSet *gCustomSubclasses; 177 | static NSMutableDictionary *gCustomSubclassMap; // maps regular classes to their custom subclasses 178 | 179 | #if COREFOUNDATION_HACK_LEVEL >= 3 180 | static CFMutableSetRef gCFWeakTargets; 181 | static NSOperationQueue *gCFDelayedDestructionQueue; 182 | #endif 183 | 184 | + (void)initialize 185 | { 186 | if(self == [MAZeroingWeakRef class]) 187 | { 188 | pthread_mutexattr_t mutexattr; 189 | pthread_mutexattr_init(&mutexattr); 190 | pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE); 191 | pthread_mutex_init(&gMutex, &mutexattr); 192 | pthread_mutexattr_destroy(&mutexattr); 193 | 194 | #if __APPLE__ 195 | gObjectWeakRefsMap = CFDictionaryCreateMutable(NULL, 0, NULL, &kCFTypeDictionaryValueCallBacks); 196 | #else 197 | gObjectWeakRefsMap = [[NSMapTable mapTableWithWeakToStrongObjects] retain]; 198 | #endif 199 | gCustomSubclasses = [[NSMutableSet alloc] init]; 200 | gCustomSubclassMap = [[NSMutableDictionary alloc] init]; 201 | 202 | // see if the 10.7 ZWR runtime functions are available 203 | // nothing special about objc_allocateClassPair, it just 204 | // seems like a reasonable and safe choice for finding 205 | // the runtime functions 206 | #if __APPLE__ 207 | Dl_info info; 208 | int success = dladdr(objc_allocateClassPair, &info); 209 | if(success) 210 | { 211 | // note: we leak the handle because it's inconsequential 212 | // and technically, the fptrs would be invalid after a dlclose 213 | void *handle = dlopen(info.dli_fname, RTLD_LAZY | RTLD_GLOBAL); 214 | if(handle) 215 | { 216 | objc_loadWeak_fptr = dlsym(handle, "objc_loadWeak"); 217 | objc_storeWeak_fptr = dlsym(handle, "objc_storeWeak"); 218 | 219 | // if either one failed, make sure both are zeroed out 220 | // this is probably unnecessary, but good paranoia 221 | if(!objc_loadWeak_fptr || !objc_storeWeak_fptr) 222 | { 223 | objc_loadWeak_fptr = NULL; 224 | objc_storeWeak_fptr = NULL; 225 | } 226 | } 227 | } 228 | #endif 229 | 230 | #if COREFOUNDATION_HACK_LEVEL >= 3 231 | gCFWeakTargets = CFSetCreateMutable(NULL, 0, NULL); 232 | gCFDelayedDestructionQueue = [[NSOperationQueue alloc] init]; 233 | #endif 234 | } 235 | } 236 | 237 | #if USE_BLOCKS_BASED_LOCKING 238 | #define BLOCK_QUALIFIER __block 239 | static void WhileLocked(void (^block)(void)) 240 | { 241 | pthread_mutex_lock(&gMutex); 242 | block(); 243 | pthread_mutex_unlock(&gMutex); 244 | } 245 | #define WhileLocked(block) WhileLocked(^block) 246 | #else 247 | #define BLOCK_QUALIFIER 248 | #define WhileLocked(block) do { \ 249 | pthread_mutex_lock(&gMutex); \ 250 | block \ 251 | pthread_mutex_unlock(&gMutex); \ 252 | } while(0) 253 | #endif 254 | 255 | static void AddWeakRefToObject(id obj, MAZeroingWeakRef *ref) 256 | { 257 | #if __APPLE__ 258 | CFMutableSetRef set = (void *)CFDictionaryGetValue(gObjectWeakRefsMap, obj); 259 | if(!set) 260 | { 261 | set = CFSetCreateMutable(NULL, 0, NULL); 262 | CFDictionarySetValue(gObjectWeakRefsMap, obj, set); 263 | CFRelease(set); 264 | } 265 | CFSetAddValue(set, ref); 266 | #else 267 | NSHashTable *set = [gObjectWeakRefsMap objectForKey:obj]; 268 | if (!set) 269 | { 270 | set = [NSHashTable hashTableWithWeakObjects]; 271 | [gObjectWeakRefsMap setObject:set forKey:obj]; 272 | } 273 | [set addObject:ref]; 274 | #endif 275 | } 276 | 277 | static void RemoveWeakRefFromObject(id obj, MAZeroingWeakRef *ref) 278 | { 279 | #if __APPLE__ 280 | CFMutableSetRef set = (void *)CFDictionaryGetValue(gObjectWeakRefsMap, obj); 281 | CFSetRemoveValue(set, ref); 282 | #else 283 | NSHashTable *set = [gObjectWeakRefsMap objectForKey:obj]; 284 | [set removeObject:ref]; 285 | #endif 286 | } 287 | 288 | static void ClearWeakRefsForObject(id obj) 289 | { 290 | #if __APPLE__ 291 | CFMutableSetRef set = (void *)CFDictionaryGetValue(gObjectWeakRefsMap, obj); 292 | if(set) 293 | { 294 | NSSet *setCopy = [[NSSet alloc] initWithSet: (NSSet *)set]; 295 | [setCopy makeObjectsPerformSelector: @selector(_zeroTarget)]; 296 | [setCopy makeObjectsPerformSelector: @selector(_executeCleanupBlockWithTarget:) withObject: obj]; 297 | [setCopy release]; 298 | CFDictionaryRemoveValue(gObjectWeakRefsMap, obj); 299 | } 300 | #else 301 | NSHashTable *set = [gObjectWeakRefsMap objectForKey:obj]; 302 | if (set) 303 | { 304 | NSArray *setContents = [set allObjects]; 305 | [setContents makeObjectsPerformSelector:@selector(_zeroTarget)]; 306 | [setContents makeObjectsPerformSelector:@selector(_executeCleanupBlockWithTarget:) withObject:obj]; 307 | [gObjectWeakRefsMap removeObjectForKey:obj]; 308 | } 309 | #endif 310 | } 311 | 312 | static Class GetCustomSubclass(id obj) 313 | { 314 | Class class = object_getClass(obj); 315 | while(class && ![gCustomSubclasses containsObject: class]) 316 | class = class_getSuperclass(class); 317 | return class; 318 | } 319 | 320 | static Class GetRealSuperclass(id obj) 321 | { 322 | Class class = GetCustomSubclass(obj); 323 | NSCAssert1(class, @"Coudn't find ZeroingWeakRef subclass in hierarchy starting from %@, should never happen", object_getClass(obj)); 324 | return class_getSuperclass(class); 325 | } 326 | 327 | static void CustomSubclassRelease(id self, SEL _cmd) 328 | { 329 | Class superclass = GetRealSuperclass(self); 330 | IMP superRelease = class_getMethodImplementation(superclass, @selector(release)); 331 | WhileLocked({ 332 | ((void (*)(id, SEL))superRelease)(self, _cmd); 333 | }); 334 | } 335 | 336 | static void CustomSubclassDealloc(id self, SEL _cmd) 337 | { 338 | ClearWeakRefsForObject(self); 339 | Class superclass = GetRealSuperclass(self); 340 | IMP superDealloc = class_getMethodImplementation(superclass, @selector(dealloc)); 341 | ((void (*)(id, SEL))superDealloc)(self, _cmd); 342 | } 343 | 344 | static Class CustomSubclassClassForCoder(id self, SEL _cmd) 345 | { 346 | Class class = GetCustomSubclass(self); 347 | Class superclass = class_getSuperclass(class); 348 | IMP superClassForCoder = class_getMethodImplementation(superclass, @selector(classForCoder)); 349 | Class classForCoder = ((id (*)(id, SEL))superClassForCoder)(self, _cmd); 350 | if(classForCoder == class) 351 | classForCoder = superclass; 352 | return classForCoder; 353 | } 354 | 355 | static void KVOSubclassRelease(id self, SEL _cmd) 356 | { 357 | IMP originalRelease = class_getMethodImplementation(object_getClass(self), @selector(MAZeroingWeakRef_KVO_original_release)); 358 | WhileLocked({ 359 | ((void (*)(id, SEL))originalRelease)(self, _cmd); 360 | }); 361 | } 362 | 363 | static void KVOSubclassDealloc(id self, SEL _cmd) 364 | { 365 | ClearWeakRefsForObject(self); 366 | IMP originalDealloc = class_getMethodImplementation(object_getClass(self), @selector(MAZeroingWeakRef_KVO_original_dealloc)); 367 | ((void (*)(id, SEL))originalDealloc)(self, _cmd); 368 | } 369 | 370 | static void KVOSubclassRemoveObserverForKeyPath(id self, SEL _cmd, id observer, NSString *keyPath) 371 | { 372 | WhileLocked({ 373 | IMP originalIMP = class_getMethodImplementation(object_getClass(self), @selector(MAZeroingWeakRef_KVO_original_removeObserver:forKeyPath:)); 374 | ((void (*)(id, SEL, id, NSString *))originalIMP)(self, _cmd, observer, keyPath); 375 | 376 | EnsureCustomSubclass(self); 377 | }); 378 | } 379 | 380 | static void KVOSubclassRemoveObserverForKeyPathContext(id self, SEL _cmd, id observer, NSString *keyPath, void *context) 381 | { 382 | WhileLocked({ 383 | IMP originalIMP = class_getMethodImplementation(object_getClass(self), @selector(MAZeroingWeakRef_KVO_original_removeObserver:forKeyPath:context:)); 384 | ((void (*)(id, SEL, id, NSString *, void *))originalIMP)(self, _cmd, observer, keyPath, context); 385 | 386 | EnsureCustomSubclass(self); 387 | }); 388 | } 389 | 390 | #if COREFOUNDATION_HACK_LEVEL >= 3 391 | 392 | static void CallCFReleaseLater(CFTypeRef cf) 393 | { 394 | mach_port_t thread = mach_thread_self(); // must "release" this 395 | 396 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 397 | SEL sel = @selector(releaseLater:fromThread:); 398 | NSInvocation *inv = [NSInvocation invocationWithMethodSignature: [MAZeroingWeakRef methodSignatureForSelector: sel]]; 399 | [inv setTarget: [MAZeroingWeakRef class]]; 400 | [inv setSelector: sel]; 401 | [inv setArgument: &cf atIndex: 2]; 402 | [inv setArgument: &thread atIndex: 3]; 403 | 404 | NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithInvocation: inv]; 405 | [gCFDelayedDestructionQueue addOperation: op]; 406 | [op release]; 407 | [pool release]; 408 | } 409 | 410 | static const void *kPCThreadExited = &kPCThreadExited; 411 | static const void *kPCError = NULL; 412 | 413 | static const void *GetPC(mach_port_t thread) 414 | { 415 | #if defined(__x86_64__) 416 | x86_thread_state64_t state; 417 | unsigned int count = x86_THREAD_STATE64_COUNT; 418 | thread_state_flavor_t flavor = x86_THREAD_STATE64; 419 | #define PC_REGISTER __rip 420 | #elif defined(__i386__) 421 | i386_thread_state_t state; 422 | unsigned int count = i386_THREAD_STATE_COUNT; 423 | thread_state_flavor_t flavor = i386_THREAD_STATE; 424 | #define PC_REGISTER __eip 425 | #elif defined(__arm__) 426 | arm_thread_state_t state; 427 | unsigned int count = ARM_THREAD_STATE_COUNT; 428 | thread_state_flavor_t flavor = ARM_THREAD_STATE; 429 | #define PC_REGISTER __pc 430 | #elif defined(__ppc__) 431 | ppc_thread_state_t state; 432 | unsigned int count = PPC_THREAD_STATE_COUNT; 433 | thread_state_flavor_t flavor = PPC_THREAD_STATE; 434 | #define PC_REGISTER __srr0 435 | #elif defined(__ppc64__) 436 | ppc_thread_state64_t state; 437 | unsigned int count = PPC_THREAD_STATE64_COUNT; 438 | thread_state_flavor_t flavor = PPC_THREAD_STATE64; 439 | #define PC_REGISTER __srr0 440 | #else 441 | #error don't know how to get PC for the current architecture! 442 | #endif 443 | 444 | kern_return_t ret = thread_get_state(thread, flavor, (thread_state_t)&state, &count); 445 | if(ret == KERN_SUCCESS) 446 | return (void *)state.PC_REGISTER; 447 | else if(ret == KERN_INVALID_ARGUMENT) 448 | return kPCThreadExited; 449 | else 450 | return kPCError; 451 | } 452 | 453 | static void CustomCFFinalize(CFTypeRef cf) 454 | { 455 | WhileLocked({ 456 | if(CFSetContainsValue(gCFWeakTargets, cf)) 457 | { 458 | if(CFGetRetainCount(cf) == 1) 459 | { 460 | ClearWeakRefsForObject((id)cf); 461 | CFSetRemoveValue(gCFWeakTargets, cf); 462 | CFRetain(cf); 463 | CallCFReleaseLater(cf); 464 | } 465 | } 466 | else 467 | { 468 | void (*fptr)(CFTypeRef) = gCFOriginalFinalizes[CFGetTypeID(cf)]; 469 | if(fptr) 470 | fptr(cf); 471 | } 472 | }); 473 | } 474 | 475 | #elif COREFOUNDATION_HACK_LEVEL >= 2 476 | 477 | static void CustomCFFinalize(CFTypeRef cf) 478 | { 479 | WhileLocked({ 480 | if(CFGetRetainCount(cf) == 1) 481 | { 482 | ClearWeakRefsForObject((id)cf); 483 | void (*fptr)(CFTypeRef) = gCFOriginalFinalizes[CFGetTypeID(cf)]; 484 | if(fptr) 485 | fptr(cf); 486 | } 487 | }); 488 | } 489 | #endif 490 | 491 | static BOOL IsTollFreeBridged(Class class, id obj) 492 | { 493 | #if COREFOUNDATION_HACK_LEVEL >= 1 494 | CFTypeID typeID = CFGetTypeID(obj); 495 | Class tfbClass = __CFRuntimeObjCClassTable[typeID]; 496 | return class == tfbClass; 497 | #else 498 | NSString *className = NSStringFromClass(class); 499 | return [className hasPrefix:@"NSCF"] || [className hasPrefix:@"__NSCF"]; 500 | #endif 501 | } 502 | 503 | static BOOL IsConstantObject(id obj) 504 | { 505 | NSUInteger retainCount = [obj retainCount]; 506 | return retainCount == NSUIntegerMax || retainCount == NSIntegerMax; 507 | } 508 | 509 | #if COREFOUNDATION_HACK_LEVEL >= 3 510 | void _CFRelease(CFTypeRef cf); 511 | 512 | + (void)releaseLater: (CFTypeRef)cf fromThread: (mach_port_t)thread 513 | { 514 | BOOL retry = YES; 515 | 516 | while(retry) 517 | { 518 | BLOCK_QUALIFIER const void *pc; 519 | // ensure that the PC is outside our inner code when fetching it, 520 | // so we don't have to check for all the nested calls 521 | WhileLocked({ 522 | pc = GetPC(thread); 523 | }); 524 | 525 | if(pc != kPCError) 526 | { 527 | if(pc == kPCThreadExited || pc < (void *)CustomCFFinalize || pc > (void *)IsTollFreeBridged) 528 | { 529 | Dl_info info; 530 | int success = dladdr(pc, &info); 531 | if(success) 532 | { 533 | if(info.dli_saddr != _CFRelease) 534 | { 535 | retry = NO; // success! 536 | CFRelease(cf); 537 | mach_port_mod_refs(mach_task_self(), thread, MACH_PORT_RIGHT_SEND, -1 ); // "release" 538 | } 539 | } 540 | } 541 | } 542 | } 543 | } 544 | #endif 545 | 546 | static BOOL IsKVOSubclass(id obj) 547 | { 548 | #if KVO_HACK_LEVEL >= 1 549 | return [obj respondsToSelector: @selector(_isKVOA)] && [obj _isKVOA]; 550 | #else 551 | return [obj class] == class_getSuperclass(object_getClass(obj)); 552 | #endif 553 | } 554 | 555 | // The native ZWR capability table is conceptually a set of SHA1 hashes. 556 | // Hashes are used instead of class names because the table is large and 557 | // contains a lot of private classes. Embedding private class names in 558 | // the binary is likely to cause problems with app review. Manually 559 | // removing all private classes from the table is a lot of work. Using 560 | // hashes allows for reasonably quick checks and no private API names. 561 | // It's implemented as a tree of tables, where each individual table 562 | // maps to a single byte. The top level of the tree is a 256-entry table. 563 | // Table entries are a NULL pointer for leading bytes which aren't present 564 | // at all. Other table entries can either contain a pointer to another 565 | // table (in which case the process continues recursively), or they can 566 | // contain a pointer to a single hash. In this second case, this indicates 567 | // that this hash is the only one present in the table with that prefix 568 | // and so a simple comparison can be used to check for membership at 569 | // that point. 570 | #if __APPLE__ 571 | static BOOL HashPresentInTable(unsigned char *hash, int length, struct _NativeZWRTableEntry *table) 572 | { 573 | while(length) 574 | { 575 | struct _NativeZWRTableEntry entry = table[hash[0]]; 576 | if(entry.ptr == NULL) 577 | { 578 | return NO; 579 | } 580 | else if(!entry.isTable) 581 | { 582 | return memcmp(entry.ptr, hash + 1, length - 1) == 0; 583 | } 584 | else 585 | { 586 | hash++; 587 | length--; 588 | table = entry.ptr; 589 | } 590 | } 591 | return NO; 592 | } 593 | #endif 594 | 595 | static BOOL CanNativeZWRClass(Class c) 596 | { 597 | #if __APPLE__ 598 | if(!c) 599 | return YES; 600 | 601 | const char *name = class_getName(c); 602 | unsigned char hash[CC_SHA1_DIGEST_LENGTH]; 603 | CC_SHA1(name, (CC_LONG)strlen(name), hash); 604 | 605 | if(HashPresentInTable(hash, CC_SHA1_DIGEST_LENGTH, _MAZeroingWeakRefClassNativeWeakReferenceNotAllowedTable)) 606 | return NO; 607 | else 608 | return CanNativeZWRClass(class_getSuperclass(c)); 609 | #else 610 | return NO; 611 | #endif 612 | } 613 | 614 | static BOOL CanNativeZWR(id obj) 615 | { 616 | return CanNativeZWRClass(object_getClass(obj)); 617 | } 618 | 619 | static Class CreatePlainCustomSubclass(Class class) 620 | { 621 | NSString *newName = [NSString stringWithFormat: @"%s_MAZeroingWeakRefSubclass", class_getName(class)]; 622 | const char *newNameC = [newName UTF8String]; 623 | 624 | Class subclass = objc_allocateClassPair(class, newNameC, 0); 625 | 626 | Method release = class_getInstanceMethod(class, @selector(release)); 627 | Method dealloc = class_getInstanceMethod(class, @selector(dealloc)); 628 | Method classForCoder = class_getInstanceMethod(class, @selector(classForCoder)); 629 | class_addMethod(subclass, @selector(release), (IMP)CustomSubclassRelease, method_getTypeEncoding(release)); 630 | class_addMethod(subclass, @selector(dealloc), (IMP)CustomSubclassDealloc, method_getTypeEncoding(dealloc)); 631 | class_addMethod(subclass, @selector(classForCoder), (IMP)CustomSubclassClassForCoder, method_getTypeEncoding(classForCoder)); 632 | 633 | objc_registerClassPair(subclass); 634 | 635 | return subclass; 636 | } 637 | 638 | static void PatchKVOSubclass(Class class) 639 | { 640 | // NSLog(@"Patching KVO class %s", class_getName(class)); 641 | Method removeObserverForKeyPath = class_getInstanceMethod(class, @selector(removeObserver:forKeyPath:)); 642 | Method release = class_getInstanceMethod(class, @selector(release)); 643 | Method dealloc = class_getInstanceMethod(class, @selector(dealloc)); 644 | 645 | class_addMethod(class, 646 | @selector(MAZeroingWeakRef_KVO_original_removeObserver:forKeyPath:), 647 | method_getImplementation(removeObserverForKeyPath), 648 | method_getTypeEncoding(removeObserverForKeyPath)); 649 | class_addMethod(class, @selector(MAZeroingWeakRef_KVO_original_release), method_getImplementation(release), method_getTypeEncoding(release)); 650 | class_addMethod(class, @selector(MAZeroingWeakRef_KVO_original_dealloc), method_getImplementation(dealloc), method_getTypeEncoding(dealloc)); 651 | 652 | class_replaceMethod(class, 653 | @selector(removeObserver:forKeyPath:), 654 | (IMP)KVOSubclassRemoveObserverForKeyPath, 655 | method_getTypeEncoding(removeObserverForKeyPath)); 656 | class_replaceMethod(class, @selector(release), (IMP)KVOSubclassRelease, method_getTypeEncoding(release)); 657 | class_replaceMethod(class, @selector(dealloc), (IMP)KVOSubclassDealloc, method_getTypeEncoding(dealloc)); 658 | 659 | // The context variant is only available on 10.7/iOS5+, so only perform that override if the method actually exists. 660 | Method removeObserverForKeyPathContext = class_getInstanceMethod(class, @selector(removeObserver:forKeyPath:context:)); 661 | if(removeObserverForKeyPathContext) 662 | { 663 | class_addMethod(class, 664 | @selector(MAZeroingWeakRef_KVO_original_removeObserver:forKeyPath:context:), 665 | method_getImplementation(removeObserverForKeyPathContext), 666 | method_getTypeEncoding(removeObserverForKeyPathContext)); 667 | class_replaceMethod(class, 668 | @selector(removeObserver:forKeyPath:context:), 669 | (IMP)KVOSubclassRemoveObserverForKeyPathContext, 670 | method_getTypeEncoding(removeObserverForKeyPathContext)); 671 | 672 | } 673 | } 674 | 675 | static void RegisterCustomSubclass(Class subclass, Class superclass) 676 | { 677 | [gCustomSubclassMap setObject: subclass forKey: (id ) superclass]; 678 | [gCustomSubclasses addObject: subclass]; 679 | } 680 | 681 | static Class CreateCustomSubclass(Class class, id obj) 682 | { 683 | if(IsTollFreeBridged(class, obj)) 684 | { 685 | #if COREFOUNDATION_HACK_LEVEL >= 2 686 | CFTypeID typeID = CFGetTypeID(obj); 687 | CFRuntimeClass *cfclass = _CFRuntimeGetClassWithTypeID(typeID); 688 | 689 | if(typeID >= gCFOriginalFinalizesSize) 690 | { 691 | gCFOriginalFinalizesSize = typeID + 1; 692 | gCFOriginalFinalizes = realloc(gCFOriginalFinalizes, gCFOriginalFinalizesSize * sizeof(*gCFOriginalFinalizes)); 693 | } 694 | 695 | do { 696 | gCFOriginalFinalizes[typeID] = cfclass->finalize; 697 | } while(!OSAtomicCompareAndSwapPtrBarrier(gCFOriginalFinalizes[typeID], CustomCFFinalize, (void *)&cfclass->finalize)); 698 | #else 699 | NSCAssert2(0, @"Cannot create zeroing weak reference to object of type %@ with COREFOUNDATION_HACK_LEVEL set to %d", class, COREFOUNDATION_HACK_LEVEL); 700 | #endif 701 | return class; 702 | } 703 | else if(IsKVOSubclass(obj)) 704 | { 705 | PatchKVOSubclass(class); 706 | return class; 707 | } 708 | else 709 | { 710 | return CreatePlainCustomSubclass(class); 711 | } 712 | } 713 | 714 | static void EnsureCustomSubclass(id obj) 715 | { 716 | if(!GetCustomSubclass(obj) && !IsConstantObject(obj)) 717 | { 718 | Class class = object_getClass(obj); 719 | Class subclass = [gCustomSubclassMap objectForKey: class]; 720 | if(!subclass) 721 | { 722 | subclass = CreateCustomSubclass(class, obj); 723 | RegisterCustomSubclass(subclass, class); 724 | } 725 | 726 | // only set the class if the current one is its superclass 727 | // otherwise it's possible that it returns something farther up in the hierarchy 728 | // and so there's no need to set it then 729 | if(class_getSuperclass(subclass) == class) 730 | object_setClass(obj, subclass); 731 | } 732 | } 733 | 734 | static void RegisterRef(MAZeroingWeakRef *ref, id target) 735 | { 736 | WhileLocked({ 737 | EnsureCustomSubclass(target); 738 | AddWeakRefToObject(target, ref); 739 | #if COREFOUNDATION_HACK_LEVEL >= 3 740 | if(IsTollFreeBridged(object_getClass(target), target)) 741 | CFSetAddValue(gCFWeakTargets, target); 742 | #endif 743 | }); 744 | } 745 | 746 | static void UnregisterRef(MAZeroingWeakRef *ref) 747 | { 748 | WhileLocked({ 749 | id target = ref->_target; 750 | 751 | if(target) 752 | RemoveWeakRefFromObject(target, ref); 753 | }); 754 | } 755 | 756 | + (BOOL)canRefCoreFoundationObjects 757 | { 758 | return COREFOUNDATION_HACK_LEVEL >= 2 || objc_storeWeak_fptr; 759 | } 760 | 761 | + (id)refWithTarget: (id)target 762 | { 763 | return [[[self alloc] initWithTarget: target] autorelease]; 764 | } 765 | 766 | - (id)initWithTarget: (id)target 767 | { 768 | if((self = [self init])) 769 | { 770 | if(objc_storeWeak_fptr && CanNativeZWR(target)) 771 | { 772 | objc_storeWeak_fptr(&_target, target); 773 | _nativeZWR = YES; 774 | } 775 | else 776 | { 777 | _target = target; 778 | RegisterRef(self, target); 779 | } 780 | } 781 | return self; 782 | } 783 | 784 | - (void)dealloc 785 | { 786 | if(objc_storeWeak_fptr && _nativeZWR) 787 | objc_storeWeak_fptr(&_target, nil); 788 | else 789 | UnregisterRef(self); 790 | 791 | #if NS_BLOCKS_AVAILABLE 792 | [_cleanupBlock release]; 793 | #endif 794 | [super dealloc]; 795 | } 796 | 797 | - (NSString *)description 798 | { 799 | return [NSString stringWithFormat: @"<%@: %p -> %@>", [self class], self, [self target]]; 800 | } 801 | 802 | #if NS_BLOCKS_AVAILABLE 803 | - (void)setCleanupBlock: (void (^)(id target))block 804 | { 805 | block = [block copy]; 806 | [_cleanupBlock release]; 807 | _cleanupBlock = block; 808 | 809 | if(objc_loadWeak_fptr && _nativeZWR) 810 | { 811 | // wrap a pool around this code, otherwise it artificially extends 812 | // the lifetime of the target object 813 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 814 | 815 | id target = [self target]; 816 | if(target != nil) @synchronized(target) 817 | { 818 | static void *associatedKey = &associatedKey; 819 | NSMutableSet *cleanupHelpers = objc_getAssociatedObject(target, associatedKey); 820 | 821 | if(cleanupHelpers == nil) 822 | { 823 | cleanupHelpers = [NSMutableSet set]; 824 | objc_setAssociatedObject(target, associatedKey, cleanupHelpers, OBJC_ASSOCIATION_RETAIN); 825 | } 826 | 827 | _MAZeroingWeakRefCleanupHelper *helper = [[_MAZeroingWeakRefCleanupHelper alloc] initWithRef: self target: target]; 828 | [cleanupHelpers addObject:helper]; 829 | 830 | [helper release]; 831 | } 832 | 833 | [pool release]; 834 | } 835 | } 836 | #endif 837 | 838 | - (id)target 839 | { 840 | if(objc_loadWeak_fptr && _nativeZWR) 841 | { 842 | return objc_loadWeak_fptr(&_target); 843 | } 844 | else 845 | { 846 | BLOCK_QUALIFIER id ret; 847 | WhileLocked({ 848 | ret = [_target retain]; 849 | }); 850 | return [ret autorelease]; 851 | } 852 | } 853 | 854 | - (void)_zeroTarget 855 | { 856 | _target = nil; 857 | } 858 | 859 | - (void)_executeCleanupBlockWithTarget: (id)target 860 | { 861 | #if NS_BLOCKS_AVAILABLE 862 | if(_cleanupBlock) 863 | { 864 | _cleanupBlock(target); 865 | [_cleanupBlock release]; 866 | _cleanupBlock = nil; 867 | } 868 | #endif 869 | } 870 | 871 | @end 872 | -------------------------------------------------------------------------------- /Source/MAZeroingWeakRefNativeZWRNotAllowedTable.h: -------------------------------------------------------------------------------- 1 | static void *_MAZeroingWeakRefClassPresentToken = &_MAZeroingWeakRefClassPresentToken; 2 | struct _NativeZWRTableEntry { BOOL isTable; void *ptr; }; 3 | static struct _NativeZWRTableEntry _MAZeroingWeakRefClassNativeWeakReferenceNotAllowedTable[256] = { 4 | [0x3] = { 0, (unsigned char[]){ 0x5b, 0x81, 0x42, 0xa2, 0xe, 0x20, 0xd7, 0x39, 0xf1, 0xa4, 0xa8, 0x21, 0x86, 0x1d, 0xdc, 0xa5, 0xef, 0x9, 0x34 } }, // NSTableCellView 5 | [0x5] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 6 | [0xa] = { 0, (unsigned char[]){ 0x5a, 0x2f, 0xc3, 0xa6, 0xd5, 0xfb, 0xcf, 0xcc, 0x85, 0xf2, 0x2f, 0xea, 0x16, 0xeb, 0xbf, 0xcf, 0x9e, 0x52 } }, // NSBlock 7 | [0x83] = { 0, (unsigned char[]){ 0xae, 0xc5, 0x56, 0x5, 0xce, 0xb3, 0xd5, 0x18, 0xe9, 0x30, 0xb7, 0x70, 0xf4, 0x78, 0xc9, 0xaf, 0xdd, 0x54 } }, // NSISNonNegativeVariableToBeMinimized 8 | }}, 9 | [0x7] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 10 | [0xf] = { 0, (unsigned char[]){ 0x52, 0xec, 0xf7, 0xb1, 0xe5, 0x2a, 0x7c, 0x39, 0xd4, 0x61, 0x17, 0x76, 0x26, 0x8e, 0x7a, 0x5c, 0x8f, 0xb2 } }, // NSISObjectiveVariable 11 | [0x40] = { 0, (unsigned char[]){ 0x46, 0xca, 0xad, 0x6d, 0xcc, 0x49, 0x26, 0x3c, 0x81, 0xb8, 0xb, 0xe7, 0x21, 0xcc, 0x28, 0xcf, 0xc3, 0x24 } }, // NSATSGlyphStorage 12 | }}, 13 | [0x8] = { 0, (unsigned char[]){ 0x82, 0x50, 0x66, 0x55, 0x76, 0x98, 0xb5, 0xb8, 0x56, 0x20, 0xd6, 0x1c, 0x7, 0x55, 0x4e, 0x32, 0xe0, 0xb1, 0x33 } }, // NSViewHierarchyLock 14 | [0x9] = { 0, (unsigned char[]){ 0x11, 0x7b, 0x21, 0x90, 0x28, 0xc0, 0x39, 0x90, 0x9b, 0xc5, 0xa9, 0xf, 0xaf, 0x8, 0x43, 0x9e, 0xb9, 0x9d, 0xc3 } }, // NSTableOptions 15 | [0xf] = { 0, (unsigned char[]){ 0x7d, 0x56, 0x74, 0xad, 0x93, 0x48, 0xe2, 0xbd, 0x2b, 0x5c, 0xb4, 0xf6, 0xf8, 0xd2, 0xfc, 0x47, 0xc0, 0xf4, 0xb9 } }, // _NSQuickLookWrapperDocumentWindow 16 | [0x11] = { 0, (unsigned char[]){ 0xa3, 0x61, 0xe2, 0x7d, 0xb1, 0x3e, 0xe4, 0xe1, 0xd1, 0x7a, 0xd, 0xc4, 0x74, 0x52, 0x76, 0xb0, 0xb5, 0x7e, 0xb3 } }, // _NSScalarObjectID 17 | [0x1a] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 18 | [0x44] = { 0, (unsigned char[]){ 0x3b, 0x91, 0x94, 0xd2, 0x34, 0x5e, 0x4a, 0x18, 0xd9, 0x71, 0x17, 0x2c, 0xc4, 0xfa, 0x5a, 0x71, 0x4c, 0xb5 } }, // NSCorrectionSubPanel 19 | [0xda] = { 0, (unsigned char[]){ 0x11, 0x4, 0xac, 0x59, 0xce, 0x58, 0x99, 0x8, 0x5, 0xae, 0xc7, 0x9f, 0x5f, 0x7c, 0x1e, 0xab, 0xf3, 0x12 } }, // NSISNonNegativeVariableWithDelegate 20 | }}, 21 | [0x1c] = { 0, (unsigned char[]){ 0x90, 0xdf, 0xd3, 0x6e, 0xb0, 0x87, 0xd6, 0xc4, 0xa4, 0x33, 0xd9, 0x9f, 0xf9, 0xde, 0x69, 0xf4, 0x80, 0x7d, 0xf4 } }, // NSCorrectionPanel 22 | [0x1d] = { 0, (unsigned char[]){ 0xfc, 0x3e, 0x70, 0x29, 0x9a, 0x6f, 0xbe, 0x9a, 0x3e, 0xe7, 0x56, 0x1e, 0x64, 0x13, 0xe9, 0x6a, 0xfd, 0xc9, 0xcd } }, // __NSSharedFontInstanceInfo 23 | [0x1f] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 24 | [0x3a] = { 0, (unsigned char[]){ 0x80, 0xbb, 0xa7, 0xc1, 0x41, 0xc9, 0xa5, 0x87, 0x46, 0x6c, 0xe8, 0x53, 0xf, 0x31, 0x2c, 0xe4, 0x82, 0xed } }, // NSToolbarConfigPanel 25 | [0xf5] = { 0, (unsigned char[]){ 0x26, 0xc2, 0x40, 0xf7, 0x91, 0x16, 0x9f, 0x23, 0x4e, 0x23, 0xa4, 0xfd, 0xcf, 0xe0, 0xb7, 0x12, 0xbe, 0x5 } }, // _NSBrowserTableColumnViewController 26 | }}, 27 | [0x20] = { 0, (unsigned char[]){ 0x45, 0xd6, 0x66, 0x4e, 0xd3, 0x46, 0xa2, 0x31, 0xbc, 0xd4, 0x91, 0xbb, 0xc6, 0x7f, 0xaf, 0x9a, 0x16, 0xf3, 0x55 } }, // NSSpellingPanel 28 | [0x24] = { 0, (unsigned char[]){ 0x97, 0x38, 0x41, 0x2b, 0xe7, 0x18, 0x67, 0x62, 0x5, 0xdd, 0xdf, 0xc1, 0x57, 0x59, 0x49, 0xc4, 0x16, 0x32, 0x94 } }, // NSISVariableWithDelegate 29 | [0x2b] = { 0, (unsigned char[]){ 0x1, 0xdd, 0xee, 0xa6, 0x38, 0xdf, 0x45, 0x52, 0x1, 0xa3, 0x33, 0x18, 0x2a, 0x2e, 0x17, 0x5, 0x96, 0x81, 0x4a } }, // NSManagedObjectID 30 | [0x2d] = { 0, (unsigned char[]){ 0xb6, 0x84, 0x6b, 0x6a, 0xe6, 0x48, 0x56, 0xb4, 0xb8, 0xae, 0x9, 0x8f, 0x88, 0xd4, 0x9f, 0x71, 0x8d, 0x2b, 0xf4 } }, // NSSecureTextView 31 | [0x33] = { 0, (unsigned char[]){ 0x46, 0x16, 0x4e, 0xe1, 0x47, 0x1a, 0x32, 0x82, 0x6e, 0xae, 0x61, 0xed, 0xf8, 0xe, 0x27, 0xa8, 0x76, 0xda, 0x8 } }, // __NSFontTypefaceInfo 32 | [0x35] = { 0, (unsigned char[]){ 0xc2, 0x5e, 0x22, 0xd0, 0x4b, 0x59, 0x4a, 0xfe, 0xc7, 0xb2, 0xc, 0xb5, 0x8d, 0x7, 0x4b, 0xee, 0x4a, 0x35, 0x52 } }, // _NSFullScreenUnbufferedWindow 33 | [0x37] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 34 | [0x6f] = { 0, (unsigned char[]){ 0x70, 0x43, 0x47, 0x3f, 0x14, 0x9b, 0xf8, 0x1e, 0x57, 0xcb, 0x40, 0xd6, 0x54, 0xd4, 0xd1, 0x6f, 0xc6, 0x5e } }, // _NSSlideAndCrossFadeAnimationProjectionWindow 35 | [0x72] = { 0, (unsigned char[]){ 0x9b, 0xcf, 0x5f, 0xcf, 0x88, 0x75, 0x72, 0x8e, 0xf1, 0x6c, 0xe5, 0xc8, 0x62, 0xc5, 0x5f, 0xe2, 0xcd, 0x5c } }, // NSNavNodeSharedServerController 36 | }}, 37 | [0x38] = { 0, (unsigned char[]){ 0x60, 0x5c, 0x3f, 0xa3, 0xb, 0xc3, 0x8d, 0x3e, 0x7, 0x33, 0x1e, 0x54, 0xf3, 0xed, 0x88, 0x29, 0xe, 0xaf, 0xc3 } }, // NSNavFilepathInputController 38 | [0x3a] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 39 | [0x19] = { 0, (unsigned char[]){ 0x21, 0x87, 0xa7, 0x0, 0x57, 0xb5, 0x54, 0xdf, 0x53, 0x50, 0x57, 0xe7, 0x88, 0xf6, 0x85, 0x3d, 0x5e, 0x73 } }, // _NSBrowserMatrixColumnViewController 40 | [0x29] = { 0, (unsigned char[]){ 0x2f, 0x44, 0xd9, 0xeb, 0x81, 0x1e, 0x89, 0x21, 0x38, 0x1a, 0xd1, 0x36, 0xf5, 0x1b, 0xb1, 0xf, 0xe2, 0xa5 } }, // NSAttributeDictionary 41 | }}, 42 | [0x3d] = { 0, (unsigned char[]){ 0x84, 0x79, 0x16, 0x14, 0xdb, 0x72, 0x27, 0x5, 0xb1, 0x2b, 0x8c, 0xed, 0xfb, 0x1f, 0xe6, 0x65, 0x9b, 0xa3, 0x32 } }, // NSISVariable 43 | [0x42] = { 0, (unsigned char[]){ 0x6e, 0xba, 0xa0, 0x45, 0x15, 0x86, 0x37, 0x4b, 0x30, 0x48, 0xe, 0x7b, 0xaf, 0xa, 0xd2, 0x75, 0x43, 0x10, 0xfb } }, // NSTableOptionsPanel 44 | [0x43] = { 0, (unsigned char[]){ 0xac, 0xfb, 0xb9, 0xaa, 0xde, 0xc7, 0xe3, 0xe0, 0x91, 0x32, 0x60, 0xad, 0xfe, 0xd2, 0x44, 0xfe, 0x75, 0xbc, 0x6b } }, // NSAccessoryWindow 45 | [0x44] = { 0, (unsigned char[]){ 0xe4, 0x9e, 0x1b, 0x5, 0xa9, 0x34, 0xa9, 0xd9, 0xc5, 0xa7, 0x5, 0x16, 0x3d, 0x4f, 0x15, 0x41, 0xa8, 0x45, 0x24 } }, // __NSOperationInternal 46 | [0x45] = { 0, (unsigned char[]){ 0xb8, 0xcb, 0x9f, 0xea, 0x3a, 0xf2, 0xe3, 0x30, 0x9d, 0x53, 0xc5, 0x36, 0x95, 0x4a, 0x69, 0x55, 0xea, 0x85, 0xee } }, // NSNavSharedServerController 47 | [0x48] = { 0, (unsigned char[]){ 0x57, 0x8c, 0x37, 0xc5, 0x34, 0x5, 0x21, 0x89, 0x5c, 0x4b, 0x15, 0x7, 0x9c, 0xb8, 0xff, 0x7b, 0x6e, 0xf1, 0xae } }, // NSWindow 48 | [0x4a] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 49 | [0xc] = { 0, (unsigned char[]){ 0xcd, 0x9e, 0xea, 0x1e, 0x8a, 0xea, 0xf, 0x0, 0xf3, 0xe7, 0x33, 0xb1, 0x6f, 0x5b, 0x42, 0x55, 0x55, 0x45 } }, // NSStringDrawingTextStorage 50 | [0x3e] = { 0, (unsigned char[]){ 0xc4, 0xeb, 0x56, 0x8b, 0x5, 0x8a, 0xbb, 0xbe, 0xa0, 0xdb, 0x58, 0xd2, 0x5b, 0x99, 0xef, 0xc, 0x36, 0xc0 } }, // NSDocumentRevisionsTimelineWindow 51 | }}, 52 | [0x4c] = { 0, (unsigned char[]){ 0x96, 0x73, 0x2, 0xb9, 0x44, 0xe3, 0x1f, 0xb, 0xaf, 0xab, 0xba, 0xf0, 0x1c, 0x1c, 0x12, 0x0, 0xb7, 0x86, 0xbf } }, // NSLocalWindowWrappingRemoteWindow 53 | [0x4d] = { 0, (unsigned char[]){ 0xb2, 0x61, 0xa9, 0x77, 0x21, 0xee, 0x44, 0x1c, 0x86, 0xdc, 0xcd, 0x68, 0x7c, 0x6f, 0x6d, 0xf2, 0x93, 0xed, 0x1e } }, // NSNavAdvancedSearchController 54 | [0x4e] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 55 | [0xaa] = { 0, (unsigned char[]){ 0x67, 0xf8, 0xa5, 0xc8, 0x3e, 0x19, 0x3f, 0xc0, 0x9, 0x59, 0x79, 0x51, 0xa0, 0x8e, 0xeb, 0xfb, 0x77, 0x26 } }, // _CTNativeGlyphStorage 56 | [0xd7] = { 0, (unsigned char[]){ 0xfc, 0xdd, 0x19, 0x16, 0xed, 0x7e, 0x9e, 0x83, 0x8e, 0x25, 0x5c, 0xa6, 0xe6, 0xe, 0xe1, 0x36, 0xc3, 0xb1 } }, // NSTokenTextView 57 | }}, 58 | [0x50] = { 0, (unsigned char[]){ 0xb2, 0x2e, 0x2a, 0x97, 0xb4, 0x8, 0x61, 0xa9, 0x51, 0x72, 0x20, 0x74, 0xbf, 0x85, 0xe4, 0x54, 0xb3, 0x1a, 0x24 } }, // _NSCoreManagedObjectID 59 | [0x52] = { 0, (unsigned char[]){ 0xb4, 0xcf, 0x19, 0x47, 0xb8, 0xd5, 0x65, 0x56, 0x75, 0xc0, 0x46, 0xd4, 0x3c, 0x9a, 0xf2, 0x21, 0x2f, 0xc5, 0xca } }, // _PFManagedObjectReferenceQueue 60 | [0x53] = { 0, (unsigned char[]){ 0x4d, 0xe5, 0x8d, 0xa1, 0x40, 0xcb, 0x7a, 0x1a, 0x27, 0xd3, 0x89, 0x24, 0x39, 0xda, 0xd1, 0x46, 0x1c, 0xf0, 0x84 } }, // NSProgressPanel 61 | [0x54] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 62 | [0x77] = { 0, (unsigned char[]){ 0x65, 0xbb, 0x28, 0x9e, 0xbd, 0x9f, 0x5d, 0xc, 0x39, 0x70, 0x5b, 0xe7, 0x65, 0xcc, 0x3c, 0xcc, 0x4a, 0x6 } }, // NSMessagePort 63 | [0xa4] = { 0, (unsigned char[]){ 0x4f, 0x92, 0x89, 0xe2, 0x3b, 0x49, 0x6e, 0x70, 0xe1, 0x75, 0x90, 0x79, 0xbb, 0x53, 0x5f, 0x4f, 0xcc, 0x3e } }, // NSColorPopoverController 64 | }}, 65 | [0x59] = { 0, (unsigned char[]){ 0xed, 0xef, 0x25, 0x8c, 0xc5, 0x35, 0xe7, 0xa3, 0xa7, 0x5a, 0xcc, 0xd3, 0x75, 0x8, 0x43, 0xb2, 0xa, 0xee, 0xb2 } }, // NSPort 66 | [0x5b] = { 0, (unsigned char[]){ 0x8a, 0x1d, 0xa9, 0x7e, 0x72, 0x5d, 0x70, 0x81, 0xcf, 0xc, 0xe0, 0xb8, 0x73, 0x8f, 0x5c, 0x85, 0xd6, 0xa1, 0xe1 } }, // _NSBrowserPreviewColumnViewController 67 | [0x5f] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 68 | [0x22] = { 0, (unsigned char[]){ 0x72, 0x59, 0x13, 0xf8, 0x71, 0xdb, 0x3a, 0xbe, 0xa0, 0x1b, 0xaf, 0xed, 0x76, 0xb, 0x9a, 0xf3, 0x5e, 0xd8 } }, // NSBasicObjectID 69 | [0xc0] = { 0, (unsigned char[]){ 0x5e, 0x88, 0x3a, 0xb1, 0x91, 0x9c, 0xf9, 0x9d, 0x19, 0xfe, 0x79, 0xa9, 0x8f, 0x7a, 0x42, 0x3, 0x7c, 0x72 } }, // _NSSavePanelTextView 70 | }}, 71 | [0x67] = { 0, (unsigned char[]){ 0xae, 0xaf, 0x59, 0x8c, 0xa3, 0x4a, 0xf8, 0xe9, 0xa, 0xe8, 0x7c, 0x18, 0x48, 0x0, 0x34, 0xbc, 0x4a, 0x69, 0x40 } }, // NSRulerMarkerPanel 72 | [0x68] = { 0, (unsigned char[]){ 0x3a, 0x65, 0xf1, 0xba, 0x6a, 0x7f, 0xa7, 0xfb, 0x12, 0xe4, 0x1f, 0x53, 0x25, 0xad, 0x74, 0x88, 0xd, 0x73, 0x30 } }, // NSStatusBarWindow 73 | [0x69] = { 0, (unsigned char[]){ 0x20, 0xef, 0xa7, 0x58, 0xa2, 0x8c, 0xc3, 0x20, 0xa1, 0xb8, 0xcd, 0x75, 0x46, 0x40, 0xfc, 0x5, 0xae, 0x61, 0xa } }, // NSToolbarFullScreenWindow 74 | [0x6a] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 75 | [0x16] = { 0, (unsigned char[]){ 0xaf, 0x44, 0x1, 0x18, 0x5e, 0x88, 0x4d, 0x10, 0x1c, 0x26, 0x2b, 0xf7, 0xca, 0xf4, 0x9, 0xb, 0x24, 0x8e } }, // NSCarbonWindow 76 | [0x72] = { 0, (unsigned char[]){ 0x94, 0xde, 0xb9, 0xc4, 0x93, 0x86, 0xcc, 0x88, 0x1e, 0x3, 0x8b, 0x7f, 0x72, 0x7c, 0x51, 0x96, 0xfb, 0xba } }, // NSPrintPreviewController 77 | }}, 78 | [0x6e] = { 0, (unsigned char[]){ 0x7, 0x4a, 0x8f, 0xd5, 0xad, 0xa6, 0xbf, 0x62, 0x15, 0x49, 0x9a, 0x98, 0xfb, 0x9e, 0x6c, 0x9a, 0x29, 0x5e, 0x45 } }, // NSTextView 79 | [0x6f] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 80 | [0x34] = { 0, (unsigned char[]){ 0x15, 0x3d, 0x33, 0x27, 0xe2, 0x98, 0x15, 0x6b, 0xd, 0xc5, 0xb0, 0x9, 0x8e, 0x8b, 0x22, 0x40, 0x88, 0x9c } }, // __NSATSStringSegment 81 | [0xc5] = { 0, (unsigned char[]){ 0x6c, 0x2c, 0x2c, 0x37, 0xe2, 0x89, 0x72, 0x56, 0xb3, 0x7d, 0xb6, 0x2d, 0x67, 0x4c, 0xd0, 0x5f, 0x55, 0xc1 } }, // NSSubTextStorage 82 | }}, 83 | [0x72] = { 0, (unsigned char[]){ 0x8d, 0x27, 0x74, 0x97, 0x62, 0x6, 0x8b, 0x6b, 0xec, 0x92, 0x51, 0x4a, 0xbd, 0x43, 0xc8, 0xaa, 0x6c, 0x58, 0x9 } }, // NSTextViewCompletionWindow 84 | [0x73] = { 0, (unsigned char[]){ 0xb1, 0xc6, 0x4b, 0x54, 0xb0, 0x56, 0x42, 0x26, 0xd0, 0xc, 0xf4, 0x28, 0x23, 0x12, 0x37, 0xad, 0xb4, 0x7d, 0xac } }, // _NSFullScreenTransitionOverlayWindow 85 | [0x75] = { 0, (unsigned char[]){ 0x4b, 0xe3, 0x5c, 0xb0, 0x20, 0x14, 0xca, 0x8c, 0x61, 0x60, 0xdc, 0x7a, 0xee, 0xf, 0x88, 0x19, 0x9f, 0xa7, 0x68 } }, // _PFTask 86 | [0x76] = { 0, (unsigned char[]){ 0xf5, 0x2d, 0xe3, 0x23, 0x10, 0x98, 0x61, 0xac, 0x59, 0x99, 0x59, 0xda, 0x3d, 0x8d, 0xa6, 0xa, 0x67, 0x37, 0xc0 } }, // NSParagraphStyle 87 | [0x77] = { 0, (unsigned char[]){ 0xe0, 0xd5, 0x7, 0x83, 0xa7, 0x2e, 0x7e, 0xba, 0xac, 0x6a, 0xaa, 0x97, 0x47, 0x4f, 0xb4, 0x26, 0xe8, 0xd5, 0xca } }, // _NSOrderOutAnimationProxyWindow 88 | [0x7c] = { 0, (unsigned char[]){ 0xdd, 0x75, 0x76, 0xb0, 0xb1, 0xfc, 0xcb, 0x3e, 0xd7, 0x51, 0xe3, 0xf4, 0x93, 0x78, 0xd5, 0x27, 0xc2, 0x4c, 0xc4 } }, // NSPrintPanelOldAccessoryController 89 | [0x7d] = { 0, (unsigned char[]){ 0x76, 0x18, 0xf6, 0x67, 0x49, 0xf0, 0x27, 0xd0, 0x31, 0x14, 0xf3, 0xce, 0x4d, 0x6e, 0x95, 0x26, 0x95, 0xa1, 0xb9 } }, // NSNavProgressStatusViewController 90 | [0x7f] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 91 | [0x18] = { 0, (unsigned char[]){ 0x3a, 0xe7, 0x3a, 0x47, 0xa1, 0x86, 0x5c, 0x8b, 0x3d, 0xad, 0x74, 0xe7, 0x7b, 0xa3, 0x71, 0xce, 0xb6, 0xed } }, // NSWindowController 92 | [0xb5] = { 0, (unsigned char[]){ 0x68, 0x7e, 0xc6, 0xa1, 0xb8, 0x14, 0xb3, 0x1b, 0xd2, 0xec, 0xce, 0x99, 0x3e, 0x3, 0x72, 0x1d, 0x17, 0xce } }, // NSTextTab 93 | }}, 94 | [0x83] = { 0, (unsigned char[]){ 0x11, 0x3f, 0x29, 0x8e, 0x75, 0xfa, 0x19, 0xca, 0x82, 0x5f, 0xc, 0xe6, 0x40, 0x60, 0x99, 0xa5, 0xcc, 0xb0, 0xd5 } }, // _NSFullScreenWindow 95 | [0x84] = { 0, (unsigned char[]){ 0x5d, 0x46, 0x99, 0xf2, 0x6f, 0x3e, 0x70, 0xd0, 0x7, 0x4, 0x32, 0x68, 0x82, 0x5d, 0xad, 0xdb, 0x5d, 0x96, 0x89 } }, // NSISNonNegativeMarkerVariable 96 | [0x89] = { 0, (unsigned char[]){ 0xe8, 0x30, 0xee, 0xf9, 0x87, 0x23, 0xd7, 0x55, 0x41, 0x71, 0xfe, 0xbd, 0x6a, 0x6a, 0x9, 0xf8, 0xa8, 0xa9, 0xb0 } }, // NSCarbonMenuWindow 97 | [0x8e] = { 0, (unsigned char[]){ 0x3c, 0x39, 0xef, 0xfb, 0x5e, 0xbf, 0xfc, 0x69, 0x9f, 0xdb, 0xd7, 0x4c, 0x97, 0xaf, 0x9f, 0xc7, 0xbf, 0xe7, 0x5 } }, // __NSFinalizingBlock 98 | [0x91] = { 0, (unsigned char[]){ 0x29, 0xe6, 0xff, 0x9c, 0xa8, 0x1b, 0x78, 0x33, 0x5e, 0xf5, 0xd6, 0xf6, 0xf3, 0x34, 0xa9, 0x27, 0x68, 0xdc, 0x48 } }, // NSISNonNegativeVariableWithDelegateToBeMinimized 99 | [0x93] = { 0, (unsigned char[]){ 0x6b, 0x15, 0xf9, 0xf2, 0xb9, 0xfb, 0x86, 0x42, 0xb2, 0x9d, 0x76, 0xaa, 0x9a, 0x3e, 0xaf, 0x47, 0x3b, 0x4b, 0x97 } }, // _NSDuplicateDocumentAnimationProjectionWindow 100 | [0x95] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 101 | [0x1f] = { 0, (unsigned char[]){ 0xc2, 0x2d, 0x6b, 0x81, 0x8b, 0xc6, 0x6d, 0x62, 0x89, 0x92, 0x68, 0x5f, 0x4b, 0x54, 0x74, 0xbc, 0x1b, 0x43 } }, // NSExceptionAlertController 102 | [0xca] = { 0, (unsigned char[]){ 0x6b, 0x18, 0xe4, 0xc5, 0xf8, 0x35, 0xae, 0x2c, 0xc1, 0x2c, 0xdc, 0xcd, 0xec, 0x4e, 0xca, 0x76, 0x94, 0x6 } }, // NSColorSpace 103 | }}, 104 | [0x96] = { 0, (unsigned char[]){ 0x9f, 0x99, 0xf9, 0x49, 0x2a, 0xc, 0xfe, 0x8, 0x4e, 0xed, 0xd4, 0x2b, 0x69, 0x39, 0xef, 0x12, 0xba, 0x18, 0x2 } }, // NSToolTipPanel 105 | [0x97] = { 0, (unsigned char[]){ 0x20, 0x8, 0xb2, 0x87, 0x77, 0xe3, 0xa4, 0x7e, 0xbe, 0x34, 0x6f, 0x84, 0x29, 0xa6, 0x21, 0x2a, 0x7f, 0xcc, 0xe } }, // __NSAutoBlock 106 | [0x98] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 107 | [0x4a] = { 0, (unsigned char[]){ 0xd, 0xf9, 0x7b, 0xf8, 0x20, 0x1c, 0xc6, 0x40, 0x43, 0x6, 0x7, 0x6c, 0x14, 0xd7, 0x25, 0x21, 0x25, 0xb7 } }, // NSSingleLineTypesetter 108 | [0xb2] = { 0, (unsigned char[]){ 0xb6, 0xb4, 0x58, 0x5d, 0x2a, 0x3c, 0xc, 0xc8, 0x27, 0xe7, 0x6e, 0x63, 0x7, 0x7e, 0x53, 0xb2, 0x50, 0x59 } }, // NSCollectionViewItem 109 | [0xdf] = { 0, (unsigned char[]){ 0xf3, 0x3a, 0x92, 0xb7, 0x1a, 0x77, 0x8f, 0xf7, 0x45, 0x92, 0xd0, 0x22, 0x18, 0xb0, 0xcc, 0xc5, 0x4f, 0x96 } }, // NSScalarObjectID64 110 | }}, 111 | [0x9a] = { 0, (unsigned char[]){ 0x57, 0xa6, 0xe7, 0x54, 0xa2, 0xbc, 0xe6, 0x20, 0x28, 0x42, 0x60, 0x93, 0x3, 0x14, 0x9d, 0xdf, 0xdb, 0xda, 0x4f } }, // NSSidebarImage 112 | [0x9d] = { 0, (unsigned char[]){ 0xb3, 0x81, 0xc4, 0xce, 0x4b, 0x48, 0x6d, 0x80, 0x6a, 0xf4, 0xe1, 0x31, 0xda, 0x8d, 0xc7, 0x83, 0xab, 0xc5, 0xa1 } }, // NSPanel 113 | [0xa0] = { 0, (unsigned char[]){ 0x63, 0xb, 0xc2, 0xb6, 0xbe, 0xf6, 0xc3, 0x86, 0x47, 0x7, 0xe, 0xd8, 0xef, 0xff, 0x92, 0xe5, 0x31, 0xe9, 0x0 } }, // NSComboBoxWindow 114 | [0xa2] = { 0, (unsigned char[]){ 0x83, 0x8d, 0xd0, 0xff, 0xa3, 0x36, 0x89, 0xef, 0x62, 0xbc, 0xb5, 0xd6, 0xbb, 0x7a, 0x4b, 0xf6, 0xf6, 0xb1, 0xfb } }, // NSViewController 115 | [0xa6] = { 0, (unsigned char[]){ 0xe8, 0x41, 0xe7, 0xac, 0x58, 0xf6, 0x21, 0x64, 0x82, 0xad, 0xa8, 0x65, 0x1a, 0x54, 0x58, 0x8c, 0xd3, 0x54, 0xa0 } }, // _NSNonretainedFullScreenWindow 116 | [0xa9] = { 0, (unsigned char[]){ 0x2f, 0xd9, 0xc0, 0xea, 0xae, 0x7d, 0x3, 0xd8, 0x5e, 0xbe, 0x67, 0xee, 0x5f, 0xb0, 0x60, 0xd0, 0x57, 0x7a, 0x5c } }, // _NSAutomaticFocusRingOverlayWindow 117 | [0xaa] = { 0, (unsigned char[]){ 0x9b, 0x75, 0x33, 0xf, 0xa8, 0xfa, 0xda, 0x8d, 0x4a, 0xd6, 0x4c, 0x43, 0x12, 0x47, 0x4d, 0x10, 0xb2, 0xc0, 0xa0 } }, // NSNavProgressWindowController 118 | [0xab] = { 0, (unsigned char[]){ 0xed, 0xd5, 0xe6, 0xe8, 0xac, 0x1, 0xd, 0x20, 0x57, 0x7f, 0x71, 0xfd, 0x18, 0xcc, 0x69, 0x72, 0xa, 0x1d, 0x42 } }, // _NSCachedAttributedString 119 | [0xac] = { 0, (unsigned char[]){ 0x62, 0xbc, 0xb9, 0x26, 0xdd, 0x24, 0x3d, 0x3f, 0xc4, 0x26, 0x47, 0x50, 0xc6, 0xbb, 0x6b, 0x56, 0x93, 0x16, 0x2c } }, // NSLineFragmentRenderingContext 120 | [0xad] = { 0, (unsigned char[]){ 0x75, 0xf9, 0xaa, 0x1b, 0xf9, 0x53, 0x93, 0x35, 0xe3, 0x16, 0x98, 0xfc, 0x7e, 0xe5, 0xec, 0x9b, 0xca, 0x64, 0xef } }, // NSFindPatternFieldEditor 121 | [0xae] = { 0, (unsigned char[]){ 0xd, 0x3, 0x25, 0x76, 0x1f, 0x1f, 0x45, 0x58, 0x25, 0xb8, 0x8f, 0xa8, 0x37, 0x72, 0xfd, 0xf5, 0xb7, 0xf1, 0x85 } }, // PBOXMenuWindow 122 | [0xb0] = { 0, (unsigned char[]){ 0x40, 0x9, 0xa1, 0xd9, 0xb4, 0xf, 0x4, 0xb6, 0x4, 0xd6, 0xd5, 0x7b, 0x9d, 0xdf, 0x9e, 0x8, 0xa2, 0xe4, 0xb7 } }, // NSMachPort 123 | [0xb1] = { 0, (unsigned char[]){ 0x7e, 0x84, 0xd, 0x23, 0x8f, 0x79, 0x56, 0xff, 0x92, 0x40, 0x76, 0xb0, 0x6b, 0x81, 0x76, 0x96, 0xf, 0xc1, 0xa } }, // __NSAutoBlock__ 124 | [0xb4] = { 0, (unsigned char[]){ 0x69, 0x23, 0xfd, 0xe9, 0xf, 0x24, 0x19, 0xb7, 0xa7, 0x92, 0xe1, 0xed, 0x1b, 0xd1, 0xa0, 0xae, 0x64, 0x85, 0x87 } }, // NSExternalRefCountedData 125 | [0xbc] = { 0, (unsigned char[]){ 0x7b, 0x3e, 0x3c, 0xe7, 0xe3, 0x14, 0x1b, 0x46, 0x77, 0x44, 0xdb, 0x43, 0xc3, 0xa4, 0xb9, 0x31, 0x66, 0x8, 0xc7 } }, // _NSFlippedImage 126 | [0xbe] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 127 | [0x66] = { 0, (unsigned char[]){ 0x1a, 0x9f, 0x99, 0xf3, 0x4a, 0xb9, 0xa7, 0xb0, 0x6, 0xad, 0xc1, 0x81, 0xdf, 0xe2, 0x1e, 0x1, 0x8b, 0xf4 } }, // _NSBorderlessLayerTreeProjectionWindow 128 | [0xab] = { 0, (unsigned char[]){ 0x49, 0x7d, 0x5f, 0x63, 0xfe, 0xdc, 0xa7, 0x43, 0x43, 0xad, 0x24, 0x80, 0x6c, 0xeb, 0x36, 0x4, 0xd2, 0x9b } }, // NSFontPanel 129 | }}, 130 | [0xbf] = { 0, (unsigned char[]){ 0x83, 0x4b, 0x26, 0xf2, 0xc3, 0x24, 0xc5, 0x64, 0x5d, 0x4c, 0x96, 0x86, 0xed, 0x42, 0x1c, 0x83, 0x5, 0x34, 0x8c } }, // NSNavProgressErrorViewController 131 | [0xc1] = { 0, (unsigned char[]){ 0x94, 0xb4, 0x7c, 0xba, 0xa4, 0xf5, 0x3a, 0x43, 0x6, 0xa3, 0x84, 0x64, 0xeb, 0xf7, 0xe0, 0xe0, 0xb6, 0x98, 0x55 } }, // NSText 132 | [0xc3] = { 0, (unsigned char[]){ 0x2e, 0x12, 0x59, 0xba, 0x72, 0xd7, 0x51, 0x40, 0x73, 0xe3, 0xe1, 0xfb, 0x1e, 0x97, 0xb0, 0xc5, 0xc1, 0xe4, 0xeb } }, // _NSTextFinderOverlayWindow 133 | [0xcd] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 134 | [0x1b] = { 0, (unsigned char[]){ 0x3b, 0x80, 0x3f, 0x14, 0x9c, 0xde, 0xad, 0x18, 0x4b, 0xe9, 0x44, 0xba, 0x1, 0x5f, 0x8, 0x98, 0xd6, 0x8c } }, // __NSStackBlock 135 | [0x81] = { 0, (unsigned char[]){ 0xa9, 0x68, 0x44, 0x6c, 0xfc, 0x5b, 0x40, 0xfe, 0x10, 0xb4, 0xc3, 0x4e, 0x19, 0xfd, 0x57, 0x68, 0x6c, 0xcb } }, // NSFindPanel 136 | }}, 137 | [0xd2] = { 0, (unsigned char[]){ 0x53, 0x40, 0xb2, 0xe9, 0xe7, 0xd8, 0xaa, 0xa9, 0x8c, 0x59, 0x99, 0x1, 0x9, 0x2b, 0xa9, 0x5a, 0x8c, 0x4, 0xa4 } }, // NSDocumentRevisionsWindow 138 | [0xd9] = { 0, (unsigned char[]){ 0x9, 0x12, 0x39, 0x4d, 0xa4, 0x3, 0x8b, 0x2, 0x13, 0x4a, 0xc6, 0x58, 0xd5, 0x9e, 0x50, 0x4a, 0xf0, 0x2, 0x36 } }, // NSISNonNegativeVariable 139 | [0xdb] = { 0, (unsigned char[]){ 0x1a, 0x27, 0xe4, 0x7, 0x22, 0xf5, 0x27, 0xc3, 0xcd, 0xc8, 0x2b, 0xb6, 0x2c, 0x25, 0x40, 0xf9, 0x46, 0xa4, 0x73 } }, // NSFont 140 | [0xdc] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 141 | [0x6] = { 0, (unsigned char[]){ 0x59, 0x16, 0xd4, 0x5a, 0xea, 0x6f, 0x8e, 0x8, 0xac, 0x89, 0xac, 0xb, 0x73, 0x2c, 0x62, 0x67, 0xff, 0x0 } }, // __NSFinalizingBlock__ 142 | [0x10] = { 0, (unsigned char[]){ 0xab, 0x59, 0x12, 0x43, 0x64, 0x12, 0x79, 0xe0, 0x82, 0xb3, 0xf9, 0xcd, 0x3b, 0xf4, 0x4d, 0x7b, 0x94, 0x25 } }, // NSPersistentUIEncodedReference 143 | }}, 144 | [0xdd] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 145 | [0x94] = { 0, (unsigned char[]){ 0x9b, 0xe, 0x2a, 0x0, 0x1b, 0x77, 0x4d, 0x1c, 0xe6, 0x22, 0x91, 0x1d, 0x0, 0xc4, 0xf2, 0x51, 0xaa, 0x77 } }, // NSFontManager 146 | [0x97] = { 0, (unsigned char[]){ 0x91, 0x5, 0x67, 0xd4, 0xed, 0x70, 0xac, 0xca, 0x54, 0x91, 0x52, 0x9a, 0x83, 0x97, 0xd2, 0x27, 0x32, 0x45 } }, // NSDockMiniViewWindow 147 | }}, 148 | [0xde] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 149 | [0x5d] = { 0, (unsigned char[]){ 0x3d, 0x4e, 0xd6, 0x7a, 0x5c, 0x6b, 0xe7, 0x4a, 0x4c, 0xa, 0xbf, 0xbe, 0x5f, 0xdf, 0x48, 0x34, 0x80, 0xe8 } }, // NSBrowserColumnViewController 150 | [0x96] = { 0, (unsigned char[]){ 0xa9, 0x1e, 0x9e, 0x35, 0x8f, 0x86, 0x47, 0x74, 0xd3, 0x6b, 0x36, 0x41, 0x53, 0x70, 0x40, 0x52, 0xaf, 0xcb } }, // __NSStackBlock__ 151 | }}, 152 | [0xe1] = { 0, (unsigned char[]){ 0xbf, 0xae, 0xbb, 0x5e, 0xb3, 0x4f, 0xa1, 0xe6, 0x4e, 0xb0, 0xd7, 0x78, 0x96, 0xba, 0x99, 0x51, 0xc6, 0x14, 0xbe } }, // NSNavPreviewController 153 | [0xe5] = { 0, (unsigned char[]){ 0xf0, 0x45, 0x53, 0x1a, 0xc8, 0x5d, 0x6b, 0xec, 0x33, 0x26, 0xf6, 0x40, 0xbe, 0x49, 0x18, 0xab, 0xd1, 0x1d, 0xa8 } }, // NSPersistentUIWindowInfo 154 | [0xe6] = { 0, (unsigned char[]){ 0x4f, 0x4f, 0xa8, 0x1f, 0x86, 0x21, 0x2b, 0x2c, 0xea, 0xab, 0xc4, 0xd5, 0x21, 0x66, 0x4c, 0xd8, 0x5b, 0xa0, 0x93 } }, // NSTypeSelectPanel 155 | [0xe8] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 156 | [0x58] = { 0, (unsigned char[]){ 0xc1, 0x9e, 0x22, 0x8f, 0x43, 0x27, 0xfc, 0xe4, 0x97, 0xfb, 0x26, 0xeb, 0x32, 0x7b, 0xaf, 0x83, 0xc1, 0x89 } }, // _NSMagnifierWindow 157 | [0x8c] = { 0, (unsigned char[]){ 0x19, 0x95, 0x99, 0x16, 0xe0, 0x53, 0x7, 0xfd, 0xe0, 0xde, 0x1c, 0x45, 0x44, 0x2f, 0xa3, 0xaf, 0xee, 0x90 } }, // NSScalarObjectID48 158 | }}, 159 | [0xe9] = { 0, (unsigned char[]){ 0xc6, 0x97, 0x40, 0x80, 0x2e, 0xc7, 0xd2, 0xbd, 0xc9, 0xd9, 0x7b, 0x21, 0x74, 0x23, 0x43, 0xf, 0xe1, 0x5a, 0x71 } }, // NSNavNodePreviewController 160 | [0xea] = { 0, (unsigned char[]){ 0x2f, 0x9f, 0x2c, 0xbf, 0x6b, 0xa7, 0x23, 0x7e, 0x64, 0x70, 0xcc, 0x75, 0x9c, 0xa9, 0xbd, 0x70, 0x2c, 0xd1, 0x66 } }, // NSATSTypesetter 161 | [0xec] = { 0, (unsigned char[]){ 0xd0, 0xc9, 0x57, 0xaf, 0xce, 0xfe, 0x15, 0xe7, 0xa3, 0xab, 0x2c, 0xda, 0x72, 0xae, 0xad, 0x17, 0x45, 0x86, 0xb1 } }, // _NSPopoverWindow 162 | [0xf1] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 163 | [0xa5] = { 0, (unsigned char[]){ 0x56, 0x9f, 0x8e, 0xfd, 0x1c, 0xc1, 0x5a, 0x15, 0xc5, 0x2, 0xd, 0x56, 0xb4, 0x1b, 0x70, 0x10, 0xdf, 0xa } }, // NSSavePanel 164 | [0xf5] = { 0, (unsigned char[]){ 0xf3, 0x38, 0xe1, 0x77, 0x44, 0x43, 0x88, 0x4, 0x36, 0x2, 0x38, 0xfc, 0xfc, 0xfb, 0xa8, 0x17, 0x4c, 0xe } }, // _NSToolbarDefaultImageRepWindow 165 | }}, 166 | [0xf2] = { 0, (unsigned char[]){ 0xce, 0x71, 0x3f, 0x21, 0x3, 0x1b, 0x57, 0x65, 0x33, 0xbf, 0xe7, 0x23, 0x4d, 0x99, 0x82, 0x1b, 0xb9, 0xf6, 0x34 } }, // NSISPureMarkerVariable 167 | [0xf3] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 168 | [0x66] = { 0, (unsigned char[]){ 0x95, 0xb6, 0xa7, 0x27, 0x66, 0x70, 0x2f, 0xc5, 0x4a, 0x38, 0xe6, 0x3b, 0x34, 0xd, 0x54, 0x21, 0x87, 0x8e } }, // NSTempAttributeDictionary 169 | [0xb8] = { 0, (unsigned char[]){ 0x8a, 0xcf, 0x23, 0xe6, 0x69, 0xe8, 0x76, 0x42, 0x9d, 0xb1, 0x4a, 0x2, 0xb1, 0x9f, 0x84, 0xa4, 0x39, 0x3e } }, // NSISNonNegativeMarkerVariableToBeMinimized 170 | [0xeb] = { 0, (unsigned char[]){ 0x5a, 0x8e, 0x70, 0xf6, 0xbf, 0x41, 0x37, 0x89, 0x2e, 0x94, 0x4b, 0x94, 0x23, 0x7d, 0x34, 0x6c, 0x46, 0xb4 } }, // NSOpenPanel 171 | }}, 172 | [0xf7] = { 0, (unsigned char[]){ 0xcc, 0x3b, 0x53, 0x10, 0x6b, 0x29, 0xa6, 0x2c, 0xbd, 0xb4, 0x33, 0x8f, 0xa2, 0x46, 0x50, 0x9f, 0x97, 0xe6, 0x77 } }, // NSImage 173 | [0xf9] = { 0, (unsigned char[]){ 0x89, 0x82, 0x91, 0xa7, 0xfc, 0x43, 0xee, 0x1b, 0x3, 0xef, 0xcc, 0x48, 0x8, 0x11, 0x51, 0x9b, 0x72, 0xe9, 0x14 } }, // NSNavNewFolderController 174 | [0xfa] = { 0, (unsigned char[]){ 0x2c, 0xb3, 0xa5, 0x1a, 0xe1, 0xa0, 0x3, 0x94, 0x42, 0xe2, 0x6c, 0xaa, 0xa1, 0xf8, 0x23, 0xb2, 0x12, 0x8e, 0xfd } }, // NSMutableParagraphStyle 175 | [0xfc] = { 1, (struct _NativeZWRTableEntry[256]) { // 1 176 | [0xd4] = { 0, (unsigned char[]){ 0x7f, 0xea, 0x1b, 0x11, 0xbf, 0xeb, 0x92, 0x57, 0x23, 0x70, 0x9, 0x12, 0x89, 0xaf, 0x84, 0xa2, 0xdf, 0x31 } }, // NSNavProgressWindow 177 | [0xd8] = { 0, (unsigned char[]){ 0x12, 0x31, 0x5f, 0x60, 0x61, 0x94, 0x7b, 0x74, 0xde, 0xd5, 0xf9, 0x34, 0x6a, 0x51, 0xff, 0x16, 0xef, 0x1e } }, // NSDrawerWindow 178 | }}, 179 | [0xff] = { 0, (unsigned char[]){ 0xd7, 0x9a, 0x4b, 0x94, 0x11, 0xb7, 0xbb, 0xb8, 0x25, 0x4d, 0x34, 0x60, 0x80, 0x46, 0xdc, 0x3a, 0x95, 0xed, 0xe3 } }, // NSLazyBrowserCell 180 | }; 181 | -------------------------------------------------------------------------------- /Source/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // ZeroingWeakRef 4 | // 5 | // Created by Michael Ash on 7/5/10. 6 | // Copyright 2010 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | 10 | #import 11 | 12 | #import 13 | 14 | #import "MANotificationCenterAdditions.h" 15 | #import "MAZeroingWeakProxy.h" 16 | #import "MAZeroingWeakRef.h" 17 | #import "MAWeakArray.h" 18 | #import "MAWeakDictionary.h" 19 | 20 | 21 | @interface NotificationReceiver : NSObject 22 | { 23 | int *_noteCounter; 24 | } 25 | 26 | - (id)initWithCounter: (int *)counter; 27 | 28 | @end 29 | 30 | @implementation NotificationReceiver 31 | 32 | - (id)initWithCounter: (int *)counter 33 | { 34 | _noteCounter = counter; 35 | return self; 36 | } 37 | 38 | - (void)gotNote: (NSNotification *)note 39 | { 40 | (*_noteCounter)++; 41 | } 42 | 43 | @end 44 | 45 | @interface KVOTargetSuperclass : NSObject {} @end 46 | @implementation KVOTargetSuperclass @end 47 | 48 | @interface KVOTarget : KVOTargetSuperclass {} @end 49 | @implementation KVOTarget 50 | 51 | - (void)setKey: (id)newValue 52 | { 53 | } 54 | 55 | - (id)key 56 | { 57 | return nil; 58 | } 59 | 60 | - (void)observeValueForKeyPath: (NSString *)keyPath ofObject: (id)object change: (NSDictionary *)change context: (void *)context 61 | { 62 | } 63 | 64 | @end 65 | 66 | static void WithPool(void (^block)(void)) 67 | { 68 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 69 | block(); 70 | [pool release]; 71 | } 72 | 73 | static int gFailureCount; 74 | 75 | void Test(void (*func)(void), const char *name) 76 | { 77 | WithPool(^{ 78 | int failureCount = gFailureCount; 79 | NSLog(@"Testing %s", name); 80 | func(); 81 | NSLog(@"%s: %s", name, failureCount == gFailureCount ? "SUCCESS" : "FAILED"); 82 | }); 83 | } 84 | 85 | BOOL TestException(void (^block)(void)) 86 | { 87 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 88 | @try { 89 | block(); 90 | return NO; 91 | } 92 | @catch (NSException * e) { 93 | return YES; 94 | } @finally { 95 | [pool drain]; 96 | } 97 | } 98 | 99 | #define TEST(func) Test(func, #func) 100 | 101 | #define TEST_EXCEPTION(block) do { \ 102 | if(!TestException(block)) { \ 103 | gFailureCount++; \ 104 | NSLog(@"%s:%d: assertion failed: exception was not thrown", __func__, __LINE__); \ 105 | } \ 106 | } while(0) 107 | 108 | #define TEST_ASSERT(cond, ...) do { \ 109 | if(!(cond)) { \ 110 | gFailureCount++; \ 111 | NSString *message = [NSString stringWithFormat: @"" __VA_ARGS__]; \ 112 | NSLog(@"%s:%d: assertion failed: %s %@", __func__, __LINE__, #cond, message); \ 113 | } \ 114 | } while(0) 115 | 116 | static BOOL WaitForNil(id (^block)(void)) 117 | { 118 | NSDate *start = [NSDate date]; 119 | __block BOOL found; 120 | do 121 | { 122 | WithPool(^{ 123 | found = block() != nil; 124 | }); 125 | } while(found && [[NSDate date] timeIntervalSinceDate:start] < 10); 126 | 127 | return !found; 128 | } 129 | 130 | static BOOL NilTarget(MAZeroingWeakRef *ref) 131 | { 132 | return WaitForNil(^{ return [ref target]; }); 133 | } 134 | 135 | static void TestBasic(void) 136 | { 137 | NSObject *obj = [[NSObject alloc] init]; 138 | MAZeroingWeakRef *ref = [[MAZeroingWeakRef alloc] initWithTarget: obj]; 139 | WithPool(^{ 140 | TEST_ASSERT([ref target]); 141 | [obj release]; 142 | }); 143 | TEST_ASSERT(NilTarget(ref), @"ref target still live after object destroyed: %@", ref); 144 | [ref release]; 145 | } 146 | 147 | static void TestRefDestroyedFirst(void) 148 | { 149 | NSObject *obj = [[NSObject alloc] init]; 150 | MAZeroingWeakRef *ref = [[MAZeroingWeakRef alloc] initWithTarget: obj]; 151 | WithPool(^{ 152 | TEST_ASSERT([ref target]); 153 | [ref release]; 154 | }); 155 | [obj release]; 156 | } 157 | 158 | static void TestDoubleRef(void) 159 | { 160 | NSObject *obj = [[NSObject alloc] init]; 161 | MAZeroingWeakRef *ref1 = [[MAZeroingWeakRef alloc] initWithTarget: obj]; 162 | MAZeroingWeakRef *ref2 = [[MAZeroingWeakRef alloc] initWithTarget: obj]; 163 | WithPool(^{ 164 | TEST_ASSERT([ref1 target]); 165 | TEST_ASSERT([ref2 target]); 166 | [obj release]; 167 | }); 168 | TEST_ASSERT(NilTarget(ref1), @"ref target still live after object destroyed: %@", ref1); 169 | TEST_ASSERT(NilTarget(ref2), @"ref target still live after object destroyed: %@", ref2); 170 | [ref1 release]; 171 | [ref2 release]; 172 | } 173 | 174 | static void TestRefToRef(void) 175 | { 176 | NSObject *obj = [[NSObject alloc] init]; 177 | MAZeroingWeakRef *ref1 = [[MAZeroingWeakRef alloc] initWithTarget: obj]; 178 | MAZeroingWeakRef *ref2 = [[MAZeroingWeakRef alloc] initWithTarget: ref1]; 179 | WithPool(^{ 180 | TEST_ASSERT([ref1 target]); 181 | TEST_ASSERT([ref2 target]); 182 | [obj release]; 183 | }); 184 | WithPool(^{ 185 | TEST_ASSERT(NilTarget(ref1), @"ref target still live after object destroyed: %@", ref1); 186 | TEST_ASSERT([ref2 target], @"ref target dead even though target ref still alive: %@", ref2); 187 | [ref1 release]; 188 | }); 189 | TEST_ASSERT(NilTarget(ref2), @"ref target still live after object destroyed: %@", ref2); 190 | [ref2 release]; 191 | } 192 | 193 | static void TestNSArrayTarget(void) 194 | { 195 | if(![MAZeroingWeakRef canRefCoreFoundationObjects]) 196 | { 197 | NSLog(@"MAZeroingWeakRef can't reference CF objects, not testing them"); 198 | return; 199 | } 200 | 201 | NSMutableArray *array = [[NSMutableArray alloc] init]; 202 | MAZeroingWeakRef *ref = [[MAZeroingWeakRef alloc] initWithTarget: array]; 203 | WithPool(^{ 204 | TEST_ASSERT([ref target]); 205 | [array release]; 206 | }); 207 | TEST_ASSERT(NilTarget(ref), @"ref target still live after object destroyed: %@", ref); 208 | [ref release]; 209 | } 210 | 211 | static void TestNSStringTarget(void) 212 | { 213 | if(![MAZeroingWeakRef canRefCoreFoundationObjects]) 214 | { 215 | NSLog(@"MAZeroingWeakRef can't reference CF objects, not testing them"); 216 | return; 217 | } 218 | 219 | NSString *str = [[NSMutableString alloc] initWithString: @"Test String"]; 220 | MAZeroingWeakRef *ref = [[MAZeroingWeakRef alloc] initWithTarget: str]; 221 | WithPool(^{ 222 | TEST_ASSERT([ref target]); 223 | [str release]; 224 | }); 225 | [ref release]; 226 | } 227 | 228 | #if __APPLE__ 229 | static void TestNSConstantTarget(void) 230 | { 231 | if ([MAZeroingWeakRef canRefCoreFoundationObjects]) { 232 | NSLog(@"MAZeroingWeakRef can reference CF objects, not testing constant object"); 233 | return; 234 | } 235 | 236 | NSString *str = @"Constant String"; 237 | MAZeroingWeakRef *ref = [[MAZeroingWeakRef alloc] initWithTarget: str]; 238 | WithPool(^{ 239 | TEST_ASSERT([ref target]); 240 | [str release]; 241 | }); 242 | [ref release]; 243 | 244 | TEST_EXCEPTION(^{ 245 | NSString *str = [[NSMutableString alloc] initWithString: @"Not Constant String"]; 246 | MAZeroingWeakRef *ref = [[MAZeroingWeakRef alloc] initWithTarget: str]; 247 | [ref release]; 248 | }); 249 | } 250 | #endif 251 | 252 | static void TestCleanup(void) 253 | { 254 | __block BOOL cleanedUp = NO; 255 | NSObject *obj = [[NSObject alloc] init]; 256 | MAZeroingWeakRef *ref = [[MAZeroingWeakRef alloc] initWithTarget: obj]; 257 | [ref setCleanupBlock: ^(id target) { cleanedUp = YES; }]; 258 | [obj release]; 259 | TEST_ASSERT(cleanedUp); 260 | [ref release]; 261 | } 262 | 263 | static void TestCFCleanup(void) 264 | { 265 | if(![MAZeroingWeakRef canRefCoreFoundationObjects]) 266 | { 267 | NSLog(@"MAZeroingWeakRef can't reference CF objects, not testing them"); 268 | return; 269 | } 270 | 271 | __block volatile BOOL cleanedUp = NO; 272 | NSObject *obj = [[NSMutableString alloc] init]; 273 | MAZeroingWeakRef *ref = [[MAZeroingWeakRef alloc] initWithTarget: obj]; 274 | [ref setCleanupBlock: ^(id target) { cleanedUp = YES; }]; 275 | [obj release]; 276 | TEST_ASSERT(WaitForNil(^{ return (id)(intptr_t)!cleanedUp; }) 277 | ); 278 | [ref release]; 279 | } 280 | 281 | #if __APPLE__ 282 | static void TestNotification(void) 283 | { 284 | int notificationCounter = 0; 285 | NotificationReceiver *receiver = [[NotificationReceiver alloc] initWithCounter: ¬ificationCounter]; 286 | [[NSNotificationCenter defaultCenter] addWeakObserver: receiver selector: @selector(gotNote:) name: @"name" object: @"object"]; 287 | [[NSNotificationCenter defaultCenter] postNotificationName: @"name" object: @"object"]; 288 | TEST_ASSERT(notificationCounter == 1); 289 | [receiver release]; 290 | [[NSNotificationCenter defaultCenter] postNotificationName: @"name" object: @"object"]; 291 | TEST_ASSERT(notificationCounter == 1); 292 | } 293 | #endif 294 | 295 | static void TestWeakArray(void) 296 | { 297 | if(![MAZeroingWeakRef canRefCoreFoundationObjects]) 298 | { 299 | NSLog(@"MAZeroingWeakRef can't reference CF objects, not testing them"); 300 | return; 301 | } 302 | 303 | NSString *str1 = [[NSMutableString alloc] initWithString: @"Test String 1"]; 304 | NSString *str2 = [[NSMutableString alloc] initWithString: @"Test String 2"]; 305 | NSString *str3 = [[NSMutableString alloc] initWithString: @"Test String 3"]; 306 | 307 | MAWeakArray *array = [[MAWeakArray alloc] init]; 308 | [array addObject: str1]; 309 | [array addObject: str2]; 310 | [array addObject: str3]; 311 | 312 | [str2 release]; 313 | 314 | WithPool(^{ 315 | TEST_ASSERT([array objectAtIndex: 0]); 316 | TEST_ASSERT(WaitForNil(^{ return [array objectAtIndex: 1]; })); 317 | TEST_ASSERT([array objectAtIndex: 2]); 318 | }); 319 | 320 | [str1 release]; 321 | [str3 release]; 322 | 323 | TEST_ASSERT(WaitForNil(^{ return [array objectAtIndex: 0]; })); 324 | TEST_ASSERT(WaitForNil(^{ return [array objectAtIndex: 1]; })); 325 | TEST_ASSERT(WaitForNil(^{ return [array objectAtIndex: 2]; })); 326 | [array release]; 327 | } 328 | 329 | static void TestWeakDictionary(void) 330 | { 331 | if(![MAZeroingWeakRef canRefCoreFoundationObjects]) 332 | { 333 | NSLog(@"MAZeroingWeakRef can't reference CF objects, not testing them"); 334 | return; 335 | } 336 | 337 | NSString *str1 = [[NSMutableString alloc] initWithString: @"Test String 1"]; 338 | NSString *str2 = [[NSMutableString alloc] initWithString: @"Test String 2"]; 339 | NSString *str3 = [[NSMutableString alloc] initWithString: @"Test String 3"]; 340 | 341 | MAWeakDictionary *dict = [[MAWeakDictionary alloc] init]; 342 | [dict setObject: str1 forKey: @"str1"]; 343 | [dict setObject: str2 forKey: @"str2"]; 344 | [dict setObject: str3 forKey: @"str3"]; 345 | 346 | [str2 release]; 347 | 348 | WithPool(^{ 349 | TEST_ASSERT([dict objectForKey: @"str1"]); 350 | TEST_ASSERT([dict objectForKey: @"str2"] == nil); 351 | TEST_ASSERT([dict objectForKey: @"str3"]); 352 | }); 353 | 354 | [str1 release]; 355 | [str3 release]; 356 | 357 | TEST_ASSERT([dict objectForKey: @"str1"] == nil); 358 | TEST_ASSERT([dict objectForKey: @"str2"] == nil); 359 | TEST_ASSERT([dict objectForKey: @"str3"] == nil); 360 | [dict release]; 361 | } 362 | 363 | static void TestWeakProxy(void) 364 | { 365 | if(![MAZeroingWeakRef canRefCoreFoundationObjects]) 366 | { 367 | NSLog(@"MAZeroingWeakRef can't reference CF objects, not testing them"); 368 | return; 369 | } 370 | 371 | NSMutableString *str = [[NSMutableString alloc] init]; 372 | NSMutableString *proxy = (NSMutableString *)[[MAZeroingWeakProxy alloc] initWithTarget: str]; 373 | 374 | WithPool(^{ 375 | TEST_ASSERT([proxy isEqual: @""]); 376 | [proxy appendString: @"Hello, world!"]; 377 | TEST_ASSERT([proxy isEqual: @"Hello, world!"]); 378 | TEST_ASSERT([proxy length] == [@"Hello, world!" length]); 379 | [proxy deleteCharactersInRange: NSMakeRange(0, 7)]; 380 | TEST_ASSERT([proxy isEqual: @"world!"]); 381 | }); 382 | 383 | [str release]; 384 | 385 | TEST_ASSERT([proxy length] == 0); 386 | TEST_ASSERT([(id)proxy zeroingProxyTarget] == nil); 387 | [proxy release]; 388 | } 389 | 390 | static void TestCleanupBlockReleasingZWR(void) 391 | { 392 | NSObject *obj = [[NSObject alloc] init]; 393 | WithPool(^{ 394 | __block MAZeroingWeakRef *ref1 = [[MAZeroingWeakRef alloc] initWithTarget: obj]; 395 | __block MAZeroingWeakRef *ref2 = [[MAZeroingWeakRef alloc] initWithTarget: obj]; 396 | __block MAZeroingWeakRef *ref3 = [[MAZeroingWeakRef alloc] initWithTarget: obj]; 397 | 398 | id cleanupBlock = ^{ 399 | [ref1 release]; 400 | ref1 = nil; 401 | [ref2 release]; 402 | ref2 = nil; 403 | [ref3 release]; 404 | ref3 = nil; 405 | }; 406 | 407 | [ref1 setCleanupBlock: cleanupBlock]; 408 | [ref2 setCleanupBlock: cleanupBlock]; 409 | [ref3 setCleanupBlock: cleanupBlock]; 410 | }); 411 | [obj release]; 412 | } 413 | 414 | static void TestAccidentalResurrectionInCleanupBlock(void) 415 | { 416 | NSObject *obj = [[NSObject alloc] init]; 417 | WithPool(^{ 418 | __block MAZeroingWeakRef *ref1 = [[MAZeroingWeakRef alloc] initWithTarget: obj]; 419 | __block MAZeroingWeakRef *ref2 = [[MAZeroingWeakRef alloc] initWithTarget: obj]; 420 | 421 | id cleanupBlock = ^{ 422 | [ref1 target]; 423 | [ref2 target]; 424 | }; 425 | 426 | [ref1 setCleanupBlock: cleanupBlock]; 427 | [ref2 setCleanupBlock: cleanupBlock]; 428 | 429 | [obj release]; 430 | [ref1 release]; 431 | [ref2 release]; 432 | }); 433 | } 434 | 435 | static void TestKVOTarget(void) 436 | { 437 | KVOTarget *target = [[KVOTarget alloc] init]; 438 | [target addObserver: target forKeyPath: @"key" options: 0 context: NULL]; 439 | 440 | MAZeroingWeakRef *ref = [[MAZeroingWeakRef alloc] initWithTarget: target]; 441 | [target setKey: @"value"]; 442 | [ref release]; 443 | } 444 | 445 | static void TestKVOMultiLevelTarget(void) 446 | { 447 | KVOTarget *target = [[KVOTarget alloc] init]; 448 | [target addObserver: target forKeyPath: @"key.whatever" options: 0 context: NULL]; 449 | 450 | MAZeroingWeakRef *ref = [[MAZeroingWeakRef alloc] initWithTarget: target]; 451 | [target removeObserver:target forKeyPath:@"key.whatever"]; 452 | [ref release]; 453 | } 454 | 455 | static void TestClassForCoder(void) 456 | { 457 | NSObject *obj = [[NSObject alloc] init]; 458 | TEST_ASSERT([obj classForCoder] == [NSObject class]); 459 | [[[MAZeroingWeakRef alloc] initWithTarget: obj] autorelease]; 460 | TEST_ASSERT([obj classForCoder] == [NSObject class]); 461 | } 462 | 463 | static void TestKVOReleaseNoCrash(void) 464 | { 465 | KVOTarget *target = [[KVOTarget alloc] init]; 466 | 467 | MAZeroingWeakRef *ref = [[MAZeroingWeakRef alloc] initWithTarget: target]; 468 | 469 | [target addObserver: target forKeyPath: @"key" options: 0 context: NULL]; 470 | 471 | [target setKey: @"value"]; 472 | 473 | // destroying target without removing the observer tosses a warning to the console 474 | // but it's necessary in order to test this failure mode 475 | [target release]; 476 | [ref target]; 477 | 478 | [ref release]; 479 | } 480 | 481 | static void TestKVOReleaseCrash(void) 482 | { 483 | KVOTarget *target = [[KVOTarget alloc] init]; 484 | 485 | [target addObserver: target forKeyPath: @"key" options: 0 context: NULL]; 486 | 487 | MAZeroingWeakRef *ref = [[MAZeroingWeakRef alloc] initWithTarget: target]; 488 | 489 | [target setKey: @"value"]; 490 | 491 | [target release]; 492 | [ref target]; 493 | 494 | [ref release]; 495 | } 496 | 497 | static void TestNativeZWRFallback(void) 498 | { 499 | NSPort *port = [NSPort port]; 500 | [MAZeroingWeakRef refWithTarget: port]; 501 | } 502 | 503 | static void TestKVORemovalCrash(void) 504 | { 505 | NSObject *obj = [[NSObject alloc] init]; 506 | NSObject *observer = [[NSObject alloc] init]; 507 | [obj addObserver:observer forKeyPath:@"description" options:NSKeyValueObservingOptionNew context:nil]; 508 | MAZeroingWeakRef *weakRef = [MAZeroingWeakRef refWithTarget:obj]; 509 | [obj removeObserver:observer forKeyPath:@"description"]; 510 | [obj release]; 511 | NSLog(@"weakRef %@", weakRef.target); 512 | [observer release]; 513 | } 514 | 515 | int main(int argc, const char * argv[]) 516 | { 517 | WithPool(^{ 518 | TEST(TestBasic); 519 | TEST(TestRefDestroyedFirst); 520 | TEST(TestDoubleRef); 521 | TEST(TestRefToRef); 522 | TEST(TestNSArrayTarget); 523 | TEST(TestNSStringTarget); 524 | #if __APPLE__ 525 | TEST(TestNSConstantTarget); 526 | #endif 527 | TEST(TestCleanup); 528 | TEST(TestCFCleanup); 529 | #if __APPLE__ 530 | TEST(TestNotification); 531 | #endif 532 | TEST(TestWeakArray); 533 | TEST(TestWeakDictionary); 534 | TEST(TestWeakProxy); 535 | TEST(TestCleanupBlockReleasingZWR); 536 | TEST(TestAccidentalResurrectionInCleanupBlock); 537 | TEST(TestKVOTarget); 538 | TEST(TestKVOMultiLevelTarget); 539 | TEST(TestClassForCoder); 540 | TEST(TestKVOReleaseNoCrash); 541 | TEST(TestKVOReleaseCrash); 542 | TEST(TestNativeZWRFallback); 543 | TEST(TestKVORemovalCrash); 544 | 545 | NSString *message; 546 | if(gFailureCount) 547 | message = [NSString stringWithFormat: @"FAILED: %d total assertion failure%s", gFailureCount, gFailureCount > 1 ? "s" : ""]; 548 | else 549 | message = @"SUCCESS"; 550 | NSLog(@"Tests complete: %@", message); 551 | }); 552 | return 0; 553 | } 554 | 555 | -------------------------------------------------------------------------------- /ZeroingWeakRef.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | C208C96011EBB8F100A8E38D /* MANotificationCenterAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = C208C95F11EBB8F100A8E38D /* MANotificationCenterAdditions.m */; }; 11 | C23912C3144A54F900AEFD01 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C23912C2144A54F900AEFD01 /* UIKit.framework */; }; 12 | C23912C4144A54F900AEFD01 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C2D7540B11E2588600816068 /* Foundation.framework */; }; 13 | C23912C6144A54F900AEFD01 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C23912C5144A54F900AEFD01 /* CoreGraphics.framework */; }; 14 | C23912CE144A54F900AEFD01 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C23912CD144A54F900AEFD01 /* main.m */; }; 15 | C2414C0D144A5F2C0029A0D4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C2D7540B11E2588600816068 /* Foundation.framework */; }; 16 | C2414C18144A5F690029A0D4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C23912CD144A54F900AEFD01 /* main.m */; }; 17 | C2414C1C144A5F8F0029A0D4 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C2414C1B144A5F8F0029A0D4 /* AppKit.framework */; }; 18 | C25675F111E25C6A00CAB48E /* MAZeroingWeakRef.m in Sources */ = {isa = PBXBuildFile; fileRef = C25675F011E25C6A00CAB48E /* MAZeroingWeakRef.m */; }; 19 | C26F610511F207270080EC96 /* MAZeroingWeakProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = C26F610411F207270080EC96 /* MAZeroingWeakProxy.m */; }; 20 | C2D7540C11E2588600816068 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C2D7540B11E2588600816068 /* Foundation.framework */; }; 21 | C2D7541011E2588600816068 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C2D7540F11E2588600816068 /* main.m */; }; 22 | C2DF1F2611ED2C1300EFC8AE /* MAWeakArray.m in Sources */ = {isa = PBXBuildFile; fileRef = C2DF1F2511ED2C1300EFC8AE /* MAWeakArray.m */; }; 23 | C2DF1F2B11ED2C4700EFC8AE /* MAWeakDictionary.m in Sources */ = {isa = PBXBuildFile; fileRef = C2DF1F2A11ED2C4700EFC8AE /* MAWeakDictionary.m */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXCopyFilesBuildPhase section */ 27 | C2414C09144A5F2C0029A0D4 /* CopyFiles */ = { 28 | isa = PBXCopyFilesBuildPhase; 29 | buildActionMask = 2147483647; 30 | dstPath = /usr/share/man/man1/; 31 | dstSubfolderSpec = 0; 32 | files = ( 33 | ); 34 | runOnlyForDeploymentPostprocessing = 1; 35 | }; 36 | C2D7540511E2588600816068 /* CopyFiles */ = { 37 | isa = PBXCopyFilesBuildPhase; 38 | buildActionMask = 2147483647; 39 | dstPath = /usr/share/man/man1/; 40 | dstSubfolderSpec = 0; 41 | files = ( 42 | ); 43 | runOnlyForDeploymentPostprocessing = 1; 44 | }; 45 | /* End PBXCopyFilesBuildPhase section */ 46 | 47 | /* Begin PBXFileReference section */ 48 | C208C95E11EBB8F100A8E38D /* MANotificationCenterAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MANotificationCenterAdditions.h; sourceTree = ""; }; 49 | C208C95F11EBB8F100A8E38D /* MANotificationCenterAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MANotificationCenterAdditions.m; sourceTree = ""; }; 50 | C23912C0144A54F900AEFD01 /* NativeZWRCheckeriPhone.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NativeZWRCheckeriPhone.app; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | C23912C2144A54F900AEFD01 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; 52 | C23912C5144A54F900AEFD01 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; }; 53 | C23912C9144A54F900AEFD01 /* NativeZWRCheckeriPhone-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "NativeZWRCheckeriPhone-Info.plist"; sourceTree = ""; }; 54 | C23912CD144A54F900AEFD01 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 55 | C2414C0B144A5F2C0029A0D4 /* NativeZWRCheckerMac */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = NativeZWRCheckerMac; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | C2414C19144A5F6F0029A0D4 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = SDKs/MacOSX10.7.sdk/System/Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; }; 57 | C2414C1B144A5F8F0029A0D4 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = SDKs/MacOSX10.7.sdk/System/Library/Frameworks/AppKit.framework; sourceTree = DEVELOPER_DIR; }; 58 | C25675EF11E25C6A00CAB48E /* MAZeroingWeakRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MAZeroingWeakRef.h; sourceTree = ""; }; 59 | C25675F011E25C6A00CAB48E /* MAZeroingWeakRef.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MAZeroingWeakRef.m; sourceTree = ""; }; 60 | C26F610311F207270080EC96 /* MAZeroingWeakProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MAZeroingWeakProxy.h; sourceTree = ""; }; 61 | C26F610411F207270080EC96 /* MAZeroingWeakProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MAZeroingWeakProxy.m; sourceTree = ""; }; 62 | C2D7540711E2588600816068 /* ZeroingWeakRef */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ZeroingWeakRef; sourceTree = BUILT_PRODUCTS_DIR; }; 63 | C2D7540B11E2588600816068 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 64 | C2D7540F11E2588600816068 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 65 | C2D7541211E2588600816068 /* ZeroingWeakRef_Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZeroingWeakRef_Prefix.pch; sourceTree = ""; }; 66 | C2DF1F2411ED2C1300EFC8AE /* MAWeakArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MAWeakArray.h; sourceTree = ""; }; 67 | C2DF1F2511ED2C1300EFC8AE /* MAWeakArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MAWeakArray.m; sourceTree = ""; }; 68 | C2DF1F2911ED2C4700EFC8AE /* MAWeakDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MAWeakDictionary.h; sourceTree = ""; }; 69 | C2DF1F2A11ED2C4700EFC8AE /* MAWeakDictionary.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MAWeakDictionary.m; sourceTree = ""; }; 70 | C2EB6F77144B37A400278198 /* MAZeroingWeakRefNativeZWRNotAllowedTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MAZeroingWeakRefNativeZWRNotAllowedTable.h; sourceTree = ""; }; 71 | /* End PBXFileReference section */ 72 | 73 | /* Begin PBXFrameworksBuildPhase section */ 74 | C23912BD144A54F900AEFD01 /* Frameworks */ = { 75 | isa = PBXFrameworksBuildPhase; 76 | buildActionMask = 2147483647; 77 | files = ( 78 | C23912C3144A54F900AEFD01 /* UIKit.framework in Frameworks */, 79 | C23912C4144A54F900AEFD01 /* Foundation.framework in Frameworks */, 80 | C23912C6144A54F900AEFD01 /* CoreGraphics.framework in Frameworks */, 81 | ); 82 | runOnlyForDeploymentPostprocessing = 0; 83 | }; 84 | C2414C08144A5F2C0029A0D4 /* Frameworks */ = { 85 | isa = PBXFrameworksBuildPhase; 86 | buildActionMask = 2147483647; 87 | files = ( 88 | C2414C1C144A5F8F0029A0D4 /* AppKit.framework in Frameworks */, 89 | C2414C0D144A5F2C0029A0D4 /* Foundation.framework in Frameworks */, 90 | ); 91 | runOnlyForDeploymentPostprocessing = 0; 92 | }; 93 | C2D7540411E2588600816068 /* Frameworks */ = { 94 | isa = PBXFrameworksBuildPhase; 95 | buildActionMask = 2147483647; 96 | files = ( 97 | C2D7540C11E2588600816068 /* Foundation.framework in Frameworks */, 98 | ); 99 | runOnlyForDeploymentPostprocessing = 0; 100 | }; 101 | /* End PBXFrameworksBuildPhase section */ 102 | 103 | /* Begin PBXGroup section */ 104 | C23912C7144A54F900AEFD01 /* NativeZWRChecker */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | C23912C9144A54F900AEFD01 /* NativeZWRCheckeriPhone-Info.plist */, 108 | C23912CD144A54F900AEFD01 /* main.m */, 109 | ); 110 | path = NativeZWRChecker; 111 | sourceTree = ""; 112 | }; 113 | C2D753FA11E2588500816068 = { 114 | isa = PBXGroup; 115 | children = ( 116 | C2414C1B144A5F8F0029A0D4 /* AppKit.framework */, 117 | C2414C19144A5F6F0029A0D4 /* Cocoa.framework */, 118 | C2D7540111E2588600816068 /* Source */, 119 | C23912C7144A54F900AEFD01 /* NativeZWRChecker */, 120 | C2D7540811E2588600816068 /* Products */, 121 | C2D7540A11E2588600816068 /* Frameworks */, 122 | C2D7541111E2588600816068 /* Other Sources */, 123 | ); 124 | sourceTree = ""; 125 | }; 126 | C2D7540111E2588600816068 /* Source */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | C2D7540F11E2588600816068 /* main.m */, 130 | C25675EF11E25C6A00CAB48E /* MAZeroingWeakRef.h */, 131 | C25675F011E25C6A00CAB48E /* MAZeroingWeakRef.m */, 132 | C26F610311F207270080EC96 /* MAZeroingWeakProxy.h */, 133 | C26F610411F207270080EC96 /* MAZeroingWeakProxy.m */, 134 | C208C95E11EBB8F100A8E38D /* MANotificationCenterAdditions.h */, 135 | C208C95F11EBB8F100A8E38D /* MANotificationCenterAdditions.m */, 136 | C2DF1F2411ED2C1300EFC8AE /* MAWeakArray.h */, 137 | C2DF1F2511ED2C1300EFC8AE /* MAWeakArray.m */, 138 | C2DF1F2911ED2C4700EFC8AE /* MAWeakDictionary.h */, 139 | C2DF1F2A11ED2C4700EFC8AE /* MAWeakDictionary.m */, 140 | C2EB6F77144B37A400278198 /* MAZeroingWeakRefNativeZWRNotAllowedTable.h */, 141 | ); 142 | path = Source; 143 | sourceTree = ""; 144 | }; 145 | C2D7540811E2588600816068 /* Products */ = { 146 | isa = PBXGroup; 147 | children = ( 148 | C2D7540711E2588600816068 /* ZeroingWeakRef */, 149 | C23912C0144A54F900AEFD01 /* NativeZWRCheckeriPhone.app */, 150 | C2414C0B144A5F2C0029A0D4 /* NativeZWRCheckerMac */, 151 | ); 152 | name = Products; 153 | sourceTree = ""; 154 | }; 155 | C2D7540A11E2588600816068 /* Frameworks */ = { 156 | isa = PBXGroup; 157 | children = ( 158 | C2D7540B11E2588600816068 /* Foundation.framework */, 159 | C23912C2144A54F900AEFD01 /* UIKit.framework */, 160 | C23912C5144A54F900AEFD01 /* CoreGraphics.framework */, 161 | ); 162 | name = Frameworks; 163 | sourceTree = ""; 164 | }; 165 | C2D7541111E2588600816068 /* Other Sources */ = { 166 | isa = PBXGroup; 167 | children = ( 168 | C2D7541211E2588600816068 /* ZeroingWeakRef_Prefix.pch */, 169 | ); 170 | name = "Other Sources"; 171 | sourceTree = ""; 172 | }; 173 | /* End PBXGroup section */ 174 | 175 | /* Begin PBXNativeTarget section */ 176 | C23912BF144A54F900AEFD01 /* NativeZWRCheckeriPhone */ = { 177 | isa = PBXNativeTarget; 178 | buildConfigurationList = C23912D5144A54F900AEFD01 /* Build configuration list for PBXNativeTarget "NativeZWRCheckeriPhone" */; 179 | buildPhases = ( 180 | C23912BC144A54F900AEFD01 /* Sources */, 181 | C23912BD144A54F900AEFD01 /* Frameworks */, 182 | C23912BE144A54F900AEFD01 /* Resources */, 183 | ); 184 | buildRules = ( 185 | ); 186 | dependencies = ( 187 | ); 188 | name = NativeZWRCheckeriPhone; 189 | productName = NativeZWRCheckeriPhone; 190 | productReference = C23912C0144A54F900AEFD01 /* NativeZWRCheckeriPhone.app */; 191 | productType = "com.apple.product-type.application"; 192 | }; 193 | C2414C0A144A5F2C0029A0D4 /* NativeZWRCheckerMac */ = { 194 | isa = PBXNativeTarget; 195 | buildConfigurationList = C2414C15144A5F2C0029A0D4 /* Build configuration list for PBXNativeTarget "NativeZWRCheckerMac" */; 196 | buildPhases = ( 197 | C2414C07144A5F2C0029A0D4 /* Sources */, 198 | C2414C08144A5F2C0029A0D4 /* Frameworks */, 199 | C2414C09144A5F2C0029A0D4 /* CopyFiles */, 200 | ); 201 | buildRules = ( 202 | ); 203 | dependencies = ( 204 | ); 205 | name = NativeZWRCheckerMac; 206 | productName = NativeZWRCheckerMac; 207 | productReference = C2414C0B144A5F2C0029A0D4 /* NativeZWRCheckerMac */; 208 | productType = "com.apple.product-type.tool"; 209 | }; 210 | C2D7540611E2588600816068 /* ZeroingWeakRef */ = { 211 | isa = PBXNativeTarget; 212 | buildConfigurationList = C2D7541511E2588600816068 /* Build configuration list for PBXNativeTarget "ZeroingWeakRef" */; 213 | buildPhases = ( 214 | C2D7540311E2588600816068 /* Sources */, 215 | C2D7540411E2588600816068 /* Frameworks */, 216 | C2D7540511E2588600816068 /* CopyFiles */, 217 | ); 218 | buildRules = ( 219 | ); 220 | dependencies = ( 221 | ); 222 | name = ZeroingWeakRef; 223 | productName = ZeroingWeakRef; 224 | productReference = C2D7540711E2588600816068 /* ZeroingWeakRef */; 225 | productType = "com.apple.product-type.tool"; 226 | }; 227 | /* End PBXNativeTarget section */ 228 | 229 | /* Begin PBXProject section */ 230 | C2D753FC11E2588500816068 /* Project object */ = { 231 | isa = PBXProject; 232 | attributes = { 233 | LastUpgradeCheck = 0510; 234 | }; 235 | buildConfigurationList = C2D753FF11E2588500816068 /* Build configuration list for PBXProject "ZeroingWeakRef" */; 236 | compatibilityVersion = "Xcode 3.2"; 237 | developmentRegion = English; 238 | hasScannedForEncodings = 0; 239 | knownRegions = ( 240 | English, 241 | Japanese, 242 | French, 243 | German, 244 | en, 245 | ); 246 | mainGroup = C2D753FA11E2588500816068; 247 | productRefGroup = C2D7540811E2588600816068 /* Products */; 248 | projectDirPath = ""; 249 | projectRoot = ""; 250 | targets = ( 251 | C2D7540611E2588600816068 /* ZeroingWeakRef */, 252 | C23912BF144A54F900AEFD01 /* NativeZWRCheckeriPhone */, 253 | C2414C0A144A5F2C0029A0D4 /* NativeZWRCheckerMac */, 254 | ); 255 | }; 256 | /* End PBXProject section */ 257 | 258 | /* Begin PBXResourcesBuildPhase section */ 259 | C23912BE144A54F900AEFD01 /* Resources */ = { 260 | isa = PBXResourcesBuildPhase; 261 | buildActionMask = 2147483647; 262 | files = ( 263 | ); 264 | runOnlyForDeploymentPostprocessing = 0; 265 | }; 266 | /* End PBXResourcesBuildPhase section */ 267 | 268 | /* Begin PBXSourcesBuildPhase section */ 269 | C23912BC144A54F900AEFD01 /* Sources */ = { 270 | isa = PBXSourcesBuildPhase; 271 | buildActionMask = 2147483647; 272 | files = ( 273 | C23912CE144A54F900AEFD01 /* main.m in Sources */, 274 | ); 275 | runOnlyForDeploymentPostprocessing = 0; 276 | }; 277 | C2414C07144A5F2C0029A0D4 /* Sources */ = { 278 | isa = PBXSourcesBuildPhase; 279 | buildActionMask = 2147483647; 280 | files = ( 281 | C2414C18144A5F690029A0D4 /* main.m in Sources */, 282 | ); 283 | runOnlyForDeploymentPostprocessing = 0; 284 | }; 285 | C2D7540311E2588600816068 /* Sources */ = { 286 | isa = PBXSourcesBuildPhase; 287 | buildActionMask = 2147483647; 288 | files = ( 289 | C2D7541011E2588600816068 /* main.m in Sources */, 290 | C25675F111E25C6A00CAB48E /* MAZeroingWeakRef.m in Sources */, 291 | C208C96011EBB8F100A8E38D /* MANotificationCenterAdditions.m in Sources */, 292 | C2DF1F2611ED2C1300EFC8AE /* MAWeakArray.m in Sources */, 293 | C2DF1F2B11ED2C4700EFC8AE /* MAWeakDictionary.m in Sources */, 294 | C26F610511F207270080EC96 /* MAZeroingWeakProxy.m in Sources */, 295 | ); 296 | runOnlyForDeploymentPostprocessing = 0; 297 | }; 298 | /* End PBXSourcesBuildPhase section */ 299 | 300 | /* Begin XCBuildConfiguration section */ 301 | C23912D3144A54F900AEFD01 /* Debug */ = { 302 | isa = XCBuildConfiguration; 303 | buildSettings = { 304 | ALWAYS_SEARCH_USER_PATHS = NO; 305 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 306 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 307 | COPY_PHASE_STRIP = NO; 308 | FRAMEWORK_SEARCH_PATHS = ( 309 | "$(inherited)", 310 | "\"$(DEVELOPER_FRAMEWORKS_DIR)\"", 311 | ); 312 | GCC_DYNAMIC_NO_PIC = NO; 313 | GCC_PREPROCESSOR_DEFINITIONS = ( 314 | "DEBUG=1", 315 | "$(inherited)", 316 | ); 317 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 318 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 319 | INFOPLIST_FILE = "NativeZWRCheckeriPhone/NativeZWRCheckeriPhone-Info.plist"; 320 | IPHONEOS_DEPLOYMENT_TARGET = 5.0; 321 | PRODUCT_NAME = "$(TARGET_NAME)"; 322 | SDKROOT = iphoneos; 323 | TARGETED_DEVICE_FAMILY = "1,2"; 324 | WRAPPER_EXTENSION = app; 325 | }; 326 | name = Debug; 327 | }; 328 | C23912D4144A54F900AEFD01 /* Release */ = { 329 | isa = XCBuildConfiguration; 330 | buildSettings = { 331 | ALWAYS_SEARCH_USER_PATHS = NO; 332 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 333 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 334 | COPY_PHASE_STRIP = YES; 335 | FRAMEWORK_SEARCH_PATHS = ( 336 | "$(inherited)", 337 | "\"$(DEVELOPER_FRAMEWORKS_DIR)\"", 338 | ); 339 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 340 | INFOPLIST_FILE = "NativeZWRCheckeriPhone/NativeZWRCheckeriPhone-Info.plist"; 341 | IPHONEOS_DEPLOYMENT_TARGET = 5.0; 342 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 343 | PRODUCT_NAME = "$(TARGET_NAME)"; 344 | SDKROOT = iphoneos; 345 | TARGETED_DEVICE_FAMILY = "1,2"; 346 | VALIDATE_PRODUCT = YES; 347 | WRAPPER_EXTENSION = app; 348 | }; 349 | name = Release; 350 | }; 351 | C2414C16144A5F2C0029A0D4 /* Debug */ = { 352 | isa = XCBuildConfiguration; 353 | buildSettings = { 354 | ALWAYS_SEARCH_USER_PATHS = NO; 355 | ARCHS = "$(ARCHS_STANDARD_64_BIT)"; 356 | COPY_PHASE_STRIP = NO; 357 | GCC_DYNAMIC_NO_PIC = NO; 358 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 359 | GCC_PREPROCESSOR_DEFINITIONS = ( 360 | "DEBUG=1", 361 | "$(inherited)", 362 | ); 363 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 364 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 365 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 366 | MACOSX_DEPLOYMENT_TARGET = 10.7; 367 | PRODUCT_NAME = "$(TARGET_NAME)"; 368 | SDKROOT = macosx; 369 | }; 370 | name = Debug; 371 | }; 372 | C2414C17144A5F2C0029A0D4 /* Release */ = { 373 | isa = XCBuildConfiguration; 374 | buildSettings = { 375 | ALWAYS_SEARCH_USER_PATHS = NO; 376 | ARCHS = "$(ARCHS_STANDARD_64_BIT)"; 377 | COPY_PHASE_STRIP = YES; 378 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 379 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 380 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 381 | GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; 382 | MACOSX_DEPLOYMENT_TARGET = 10.7; 383 | PRODUCT_NAME = "$(TARGET_NAME)"; 384 | SDKROOT = macosx; 385 | }; 386 | name = Release; 387 | }; 388 | C2D7541311E2588600816068 /* Debug */ = { 389 | isa = XCBuildConfiguration; 390 | buildSettings = { 391 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 392 | CLANG_WARN_BOOL_CONVERSION = YES; 393 | CLANG_WARN_CONSTANT_CONVERSION = YES; 394 | CLANG_WARN_EMPTY_BODY = YES; 395 | CLANG_WARN_ENUM_CONVERSION = YES; 396 | CLANG_WARN_INT_CONVERSION = YES; 397 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 398 | GCC_C_LANGUAGE_STANDARD = gnu99; 399 | GCC_OPTIMIZATION_LEVEL = 0; 400 | GCC_PREPROCESSOR_DEFINITIONS = DEBUG; 401 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 402 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 403 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 404 | GCC_WARN_UNDECLARED_SELECTOR = YES; 405 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 406 | GCC_WARN_UNUSED_FUNCTION = YES; 407 | GCC_WARN_UNUSED_VARIABLE = YES; 408 | ONLY_ACTIVE_ARCH = YES; 409 | PREBINDING = NO; 410 | }; 411 | name = Debug; 412 | }; 413 | C2D7541411E2588600816068 /* Release */ = { 414 | isa = XCBuildConfiguration; 415 | buildSettings = { 416 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 417 | CLANG_WARN_BOOL_CONVERSION = YES; 418 | CLANG_WARN_CONSTANT_CONVERSION = YES; 419 | CLANG_WARN_EMPTY_BODY = YES; 420 | CLANG_WARN_ENUM_CONVERSION = YES; 421 | CLANG_WARN_INT_CONVERSION = YES; 422 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 423 | GCC_C_LANGUAGE_STANDARD = gnu99; 424 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 425 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 426 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 427 | GCC_WARN_UNDECLARED_SELECTOR = YES; 428 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 429 | GCC_WARN_UNUSED_FUNCTION = YES; 430 | GCC_WARN_UNUSED_VARIABLE = YES; 431 | PREBINDING = NO; 432 | }; 433 | name = Release; 434 | }; 435 | C2D7541611E2588600816068 /* Debug */ = { 436 | isa = XCBuildConfiguration; 437 | buildSettings = { 438 | ALWAYS_SEARCH_USER_PATHS = NO; 439 | COPY_PHASE_STRIP = NO; 440 | GCC_DYNAMIC_NO_PIC = NO; 441 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 442 | GCC_MODEL_TUNING = G5; 443 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 444 | GCC_PREFIX_HEADER = ZeroingWeakRef_Prefix.pch; 445 | INSTALL_PATH = /usr/local/bin; 446 | PRODUCT_NAME = ZeroingWeakRef; 447 | }; 448 | name = Debug; 449 | }; 450 | C2D7541711E2588600816068 /* Release */ = { 451 | isa = XCBuildConfiguration; 452 | buildSettings = { 453 | ALWAYS_SEARCH_USER_PATHS = NO; 454 | COPY_PHASE_STRIP = YES; 455 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 456 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 457 | GCC_MODEL_TUNING = G5; 458 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 459 | GCC_PREFIX_HEADER = ZeroingWeakRef_Prefix.pch; 460 | INSTALL_PATH = /usr/local/bin; 461 | PRODUCT_NAME = ZeroingWeakRef; 462 | }; 463 | name = Release; 464 | }; 465 | /* End XCBuildConfiguration section */ 466 | 467 | /* Begin XCConfigurationList section */ 468 | C23912D5144A54F900AEFD01 /* Build configuration list for PBXNativeTarget "NativeZWRCheckeriPhone" */ = { 469 | isa = XCConfigurationList; 470 | buildConfigurations = ( 471 | C23912D3144A54F900AEFD01 /* Debug */, 472 | C23912D4144A54F900AEFD01 /* Release */, 473 | ); 474 | defaultConfigurationIsVisible = 0; 475 | defaultConfigurationName = Release; 476 | }; 477 | C2414C15144A5F2C0029A0D4 /* Build configuration list for PBXNativeTarget "NativeZWRCheckerMac" */ = { 478 | isa = XCConfigurationList; 479 | buildConfigurations = ( 480 | C2414C16144A5F2C0029A0D4 /* Debug */, 481 | C2414C17144A5F2C0029A0D4 /* Release */, 482 | ); 483 | defaultConfigurationIsVisible = 0; 484 | defaultConfigurationName = Release; 485 | }; 486 | C2D753FF11E2588500816068 /* Build configuration list for PBXProject "ZeroingWeakRef" */ = { 487 | isa = XCConfigurationList; 488 | buildConfigurations = ( 489 | C2D7541311E2588600816068 /* Debug */, 490 | C2D7541411E2588600816068 /* Release */, 491 | ); 492 | defaultConfigurationIsVisible = 0; 493 | defaultConfigurationName = Release; 494 | }; 495 | C2D7541511E2588600816068 /* Build configuration list for PBXNativeTarget "ZeroingWeakRef" */ = { 496 | isa = XCConfigurationList; 497 | buildConfigurations = ( 498 | C2D7541611E2588600816068 /* Debug */, 499 | C2D7541711E2588600816068 /* Release */, 500 | ); 501 | defaultConfigurationIsVisible = 0; 502 | defaultConfigurationName = Release; 503 | }; 504 | /* End XCConfigurationList section */ 505 | }; 506 | rootObject = C2D753FC11E2588500816068 /* Project object */; 507 | } 508 | -------------------------------------------------------------------------------- /ZeroingWeakRef.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ZeroingWeakRef.xcodeproj/project.xcworkspace/xcuserdata/mikeash.xcuserdatad/WorkspaceState.xcuserstate: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | $archiver 6 | NSKeyedArchiver 7 | $objects 8 | 9 | $null 10 | 11 | $class 12 | 13 | CF$UID 14 | 59 15 | 16 | NS.keys 17 | 18 | 19 | CF$UID 20 | 2 21 | 22 | 23 | CF$UID 24 | 3 25 | 26 | 27 | CF$UID 28 | 4 29 | 30 | 31 | NS.objects 32 | 33 | 34 | CF$UID 35 | 5 36 | 37 | 38 | CF$UID 39 | 102 40 | 41 | 42 | CF$UID 43 | 169 44 | 45 | 46 | 47 | IDEWorkspaceWindowController_1 48 | IDEWorkspaceDocument 49 | IDEWorkspaceWindowController_0 50 | 51 | $class 52 | 53 | CF$UID 54 | 60 55 | 56 | NS.keys 57 | 58 | 59 | CF$UID 60 | 6 61 | 62 | 63 | CF$UID 64 | 7 65 | 66 | 67 | CF$UID 68 | 8 69 | 70 | 71 | CF$UID 72 | 9 73 | 74 | 75 | CF$UID 76 | 10 77 | 78 | 79 | NS.objects 80 | 81 | 82 | CF$UID 83 | 11 84 | 85 | 86 | CF$UID 87 | 13 88 | 89 | 90 | CF$UID 91 | 10 92 | 93 | 94 | CF$UID 95 | 14 96 | 97 | 98 | CF$UID 99 | 15 100 | 101 | 102 | 103 | IDEOrderedWorkspaceTabControllers 104 | IDEUserWantsMiniDebuggingConsole 105 | IDEActiveWorkspaceTabController 106 | IDEWindowFrame 107 | IDEWorkspaceTabController_0 108 | 109 | $class 110 | 111 | CF$UID 112 | 12 113 | 114 | NS.objects 115 | 116 | 117 | CF$UID 118 | 10 119 | 120 | 121 | 122 | 123 | $classes 124 | 125 | NSArray 126 | NSObject 127 | 128 | $classname 129 | NSArray 130 | 131 | 0 132 | {{285, 76}, {1400, 971}} 133 | 134 | $class 135 | 136 | CF$UID 137 | 60 138 | 139 | NS.keys 140 | 141 | 142 | CF$UID 143 | 16 144 | 145 | 146 | CF$UID 147 | 17 148 | 149 | 150 | CF$UID 151 | 18 152 | 153 | 154 | CF$UID 155 | 19 156 | 157 | 158 | CF$UID 159 | 20 160 | 161 | 162 | CF$UID 163 | 21 164 | 165 | 166 | CF$UID 167 | 22 168 | 169 | 170 | NS.objects 171 | 172 | 173 | CF$UID 174 | 23 175 | 176 | 177 | CF$UID 178 | 62 179 | 180 | 181 | CF$UID 182 | 63 183 | 184 | 185 | CF$UID 186 | 73 187 | 188 | 189 | CF$UID 190 | 93 191 | 192 | 193 | CF$UID 194 | 13 195 | 196 | 197 | CF$UID 198 | 43 199 | 200 | 201 | 202 | IDEEditorArea 203 | IDEShowNavigator 204 | IDEWorkspaceTabControllerUtilityAreaSplitView 205 | IDENavigatorArea 206 | IDEWorkspaceTabControllerDesignAreaSplitView 207 | IDEShowUtilities 208 | IDETabLabel 209 | 210 | $class 211 | 212 | CF$UID 213 | 60 214 | 215 | NS.keys 216 | 217 | 218 | CF$UID 219 | 24 220 | 221 | 222 | CF$UID 223 | 25 224 | 225 | 226 | CF$UID 227 | 26 228 | 229 | 230 | NS.objects 231 | 232 | 233 | CF$UID 234 | 13 235 | 236 | 237 | CF$UID 238 | 13 239 | 240 | 241 | CF$UID 242 | 27 243 | 244 | 245 | 246 | EditorMode 247 | ShowDebuggerArea 248 | IDEEditorMode_Standard 249 | 250 | $class 251 | 252 | CF$UID 253 | 60 254 | 255 | NS.keys 256 | 257 | 258 | CF$UID 259 | 28 260 | 261 | 262 | NS.objects 263 | 264 | 265 | CF$UID 266 | 29 267 | 268 | 269 | 270 | EditorStates 271 | 272 | $class 273 | 274 | CF$UID 275 | 59 276 | 277 | NS.keys 278 | 279 | 280 | CF$UID 281 | 28 282 | 283 | 284 | CF$UID 285 | 30 286 | 287 | 288 | NS.objects 289 | 290 | 291 | CF$UID 292 | 31 293 | 294 | 295 | CF$UID 296 | 13 297 | 298 | 299 | 300 | SelectedEditorState 301 | 302 | $class 303 | 304 | CF$UID 305 | 61 306 | 307 | NS.objects 308 | 309 | 310 | CF$UID 311 | 32 312 | 313 | 314 | 315 | 316 | $class 317 | 318 | CF$UID 319 | 60 320 | 321 | NS.keys 322 | 323 | 324 | CF$UID 325 | 33 326 | 327 | 328 | CF$UID 329 | 34 330 | 331 | 332 | CF$UID 333 | 35 334 | 335 | 336 | CF$UID 337 | 36 338 | 339 | 340 | CF$UID 341 | 37 342 | 343 | 344 | CF$UID 345 | 38 346 | 347 | 348 | NS.objects 349 | 350 | 351 | CF$UID 352 | 39 353 | 354 | 355 | CF$UID 356 | 40 357 | 358 | 359 | CF$UID 360 | 47 361 | 362 | 363 | CF$UID 364 | 50 365 | 366 | 367 | CF$UID 368 | 51 369 | 370 | 371 | CF$UID 372 | 43 373 | 374 | 375 | 376 | DocumentExtensionIdentifier 377 | ArchivableRepresentation 378 | DocumentURL 379 | FileDataType 380 | EditorState 381 | HistoryMenuDescription 382 | Xcode.IDEKit.EditorDocument.SourceCode 383 | 384 | $class 385 | 386 | CF$UID 387 | 46 388 | 389 | DocumentLocation 390 | 391 | CF$UID 392 | 0 393 | 394 | DomainIdentifier 395 | 396 | CF$UID 397 | 41 398 | 399 | IdentifierPath 400 | 401 | CF$UID 402 | 42 403 | 404 | 405 | Xcode.IDENavigableItemDomain.WorkspaceStructure 406 | 407 | $class 408 | 409 | CF$UID 410 | 12 411 | 412 | NS.objects 413 | 414 | 415 | CF$UID 416 | 43 417 | 418 | 419 | CF$UID 420 | 44 421 | 422 | 423 | CF$UID 424 | 45 425 | 426 | 427 | 428 | main.m 429 | Source 430 | ZeroingWeakRef 431 | 432 | $classes 433 | 434 | IDENavigableItemArchivableRepresentation 435 | NSObject 436 | 437 | $classname 438 | IDENavigableItemArchivableRepresentation 439 | 440 | 441 | $class 442 | 443 | CF$UID 444 | 49 445 | 446 | NS.base 447 | 448 | CF$UID 449 | 0 450 | 451 | NS.relative 452 | 453 | CF$UID 454 | 48 455 | 456 | 457 | file://localhost/Users/mikeash/Development/Projects/Public/ZeroingWeakRef/Source/main.m 458 | 459 | $classes 460 | 461 | NSURL 462 | NSObject 463 | 464 | $classname 465 | NSURL 466 | 467 | public.objective-c-source 468 | 469 | $class 470 | 471 | CF$UID 472 | 59 473 | 474 | NS.keys 475 | 476 | 477 | CF$UID 478 | 52 479 | 480 | 481 | CF$UID 482 | 53 483 | 484 | 485 | NS.objects 486 | 487 | 488 | CF$UID 489 | 54 490 | 491 | 492 | CF$UID 493 | 58 494 | 495 | 496 | 497 | SelectedDocumentLocations 498 | VisibleCharacterRange 499 | 500 | $class 501 | 502 | CF$UID 503 | 12 504 | 505 | NS.objects 506 | 507 | 508 | CF$UID 509 | 55 510 | 511 | 512 | 513 | 514 | $class 515 | 516 | CF$UID 517 | 57 518 | 519 | characterRangeLen 520 | 0 521 | characterRangeLoc 522 | 0 523 | documentURL 524 | 525 | CF$UID 526 | 48 527 | 528 | endingColumnNumber 529 | -1 530 | endingLineNumber 531 | -1 532 | startingColumnNumber 533 | -1 534 | startingLineNumber 535 | -1 536 | timestamp 537 | 538 | CF$UID 539 | 56 540 | 541 | 542 | 300047385.41618598 543 | 544 | $classes 545 | 546 | DVTTextDocumentLocation 547 | DVTDocumentLocation 548 | NSObject 549 | 550 | $classname 551 | DVTTextDocumentLocation 552 | 553 | {0, 703} 554 | 555 | $classes 556 | 557 | NSDictionary 558 | NSObject 559 | 560 | $classname 561 | NSDictionary 562 | 563 | 564 | $classes 565 | 566 | NSMutableDictionary 567 | NSDictionary 568 | NSObject 569 | 570 | $classname 571 | NSMutableDictionary 572 | 573 | 574 | $classes 575 | 576 | NSMutableArray 577 | NSArray 578 | NSObject 579 | 580 | $classname 581 | NSMutableArray 582 | 583 | 1 584 | 585 | $class 586 | 587 | CF$UID 588 | 60 589 | 590 | NS.keys 591 | 592 | 593 | CF$UID 594 | 64 595 | 596 | 597 | NS.objects 598 | 599 | 600 | CF$UID 601 | 65 602 | 603 | 604 | 605 | DVTSplitViewItems 606 | 607 | $class 608 | 609 | CF$UID 610 | 61 611 | 612 | NS.objects 613 | 614 | 615 | CF$UID 616 | 66 617 | 618 | 619 | CF$UID 620 | 71 621 | 622 | 623 | 624 | 625 | $class 626 | 627 | CF$UID 628 | 59 629 | 630 | NS.keys 631 | 632 | 633 | CF$UID 634 | 67 635 | 636 | 637 | CF$UID 638 | 68 639 | 640 | 641 | NS.objects 642 | 643 | 644 | CF$UID 645 | 69 646 | 647 | 648 | CF$UID 649 | 70 650 | 651 | 652 | 653 | DVTIdentifier 654 | DVTViewMagnitude 655 | 656 | 660 657 | 658 | $class 659 | 660 | CF$UID 661 | 59 662 | 663 | NS.keys 664 | 665 | 666 | CF$UID 667 | 67 668 | 669 | 670 | CF$UID 671 | 68 672 | 673 | 674 | NS.objects 675 | 676 | 677 | CF$UID 678 | 69 679 | 680 | 681 | CF$UID 682 | 72 683 | 684 | 685 | 686 | 215 687 | 688 | $class 689 | 690 | CF$UID 691 | 60 692 | 693 | NS.keys 694 | 695 | 696 | CF$UID 697 | 74 698 | 699 | 700 | CF$UID 701 | 75 702 | 703 | 704 | NS.objects 705 | 706 | 707 | CF$UID 708 | 75 709 | 710 | 711 | CF$UID 712 | 76 713 | 714 | 715 | 716 | SelectedNavigator 717 | Xcode.IDEKit.Navigator.Structure 718 | 719 | $class 720 | 721 | CF$UID 722 | 60 723 | 724 | NS.keys 725 | 726 | 727 | CF$UID 728 | 77 729 | 730 | 731 | CF$UID 732 | 78 733 | 734 | 735 | CF$UID 736 | 79 737 | 738 | 739 | CF$UID 740 | 80 741 | 742 | 743 | CF$UID 744 | 81 745 | 746 | 747 | CF$UID 748 | 82 749 | 750 | 751 | NS.objects 752 | 753 | 754 | CF$UID 755 | 13 756 | 757 | 758 | CF$UID 759 | 83 760 | 761 | 762 | CF$UID 763 | 90 764 | 765 | 766 | CF$UID 767 | 13 768 | 769 | 770 | CF$UID 771 | 13 772 | 773 | 774 | CF$UID 775 | 91 776 | 777 | 778 | 779 | IDEUnsavedDocumentFilteringEnabled 780 | IDEExpandedItems 781 | IDEVisibleRect 782 | IDERecentDocumentFilteringEnabled 783 | IDESCMStatusFilteringEnabled 784 | IDESelectedObjects 785 | 786 | $class 787 | 788 | CF$UID 789 | 61 790 | 791 | NS.objects 792 | 793 | 794 | CF$UID 795 | 84 796 | 797 | 798 | CF$UID 799 | 85 800 | 801 | 802 | CF$UID 803 | 86 804 | 805 | 806 | CF$UID 807 | 88 808 | 809 | 810 | 811 | 812 | $class 813 | 814 | CF$UID 815 | 61 816 | 817 | NS.objects 818 | 819 | 820 | CF$UID 821 | 45 822 | 823 | 824 | 825 | 826 | $class 827 | 828 | CF$UID 829 | 61 830 | 831 | NS.objects 832 | 833 | 834 | CF$UID 835 | 45 836 | 837 | 838 | CF$UID 839 | 44 840 | 841 | 842 | 843 | 844 | $class 845 | 846 | CF$UID 847 | 61 848 | 849 | NS.objects 850 | 851 | 852 | CF$UID 853 | 45 854 | 855 | 856 | CF$UID 857 | 87 858 | 859 | 860 | 861 | Documentation 862 | 863 | $class 864 | 865 | CF$UID 866 | 61 867 | 868 | NS.objects 869 | 870 | 871 | CF$UID 872 | 45 873 | 874 | 875 | CF$UID 876 | 89 877 | 878 | 879 | 880 | Products 881 | {{0, 0}, {259, 832}} 882 | 883 | $class 884 | 885 | CF$UID 886 | 61 887 | 888 | NS.objects 889 | 890 | 891 | CF$UID 892 | 92 893 | 894 | 895 | 896 | 897 | $class 898 | 899 | CF$UID 900 | 61 901 | 902 | NS.objects 903 | 904 | 905 | CF$UID 906 | 45 907 | 908 | 909 | CF$UID 910 | 44 911 | 912 | 913 | CF$UID 914 | 43 915 | 916 | 917 | 918 | 919 | $class 920 | 921 | CF$UID 922 | 60 923 | 924 | NS.keys 925 | 926 | 927 | CF$UID 928 | 64 929 | 930 | 931 | NS.objects 932 | 933 | 934 | CF$UID 935 | 94 936 | 937 | 938 | 939 | 940 | $class 941 | 942 | CF$UID 943 | 61 944 | 945 | NS.objects 946 | 947 | 948 | CF$UID 949 | 95 950 | 951 | 952 | CF$UID 953 | 97 954 | 955 | 956 | CF$UID 957 | 99 958 | 959 | 960 | 961 | 962 | $class 963 | 964 | CF$UID 965 | 59 966 | 967 | NS.keys 968 | 969 | 970 | CF$UID 971 | 67 972 | 973 | 974 | CF$UID 975 | 68 976 | 977 | 978 | NS.objects 979 | 980 | 981 | CF$UID 982 | 19 983 | 984 | 985 | CF$UID 986 | 96 987 | 988 | 989 | 990 | 260 991 | 992 | $class 993 | 994 | CF$UID 995 | 59 996 | 997 | NS.keys 998 | 999 | 1000 | CF$UID 1001 | 67 1002 | 1003 | 1004 | CF$UID 1005 | 68 1006 | 1007 | 1008 | NS.objects 1009 | 1010 | 1011 | CF$UID 1012 | 16 1013 | 1014 | 1015 | CF$UID 1016 | 98 1017 | 1018 | 1019 | 1020 | 1140 1021 | 1022 | $class 1023 | 1024 | CF$UID 1025 | 59 1026 | 1027 | NS.keys 1028 | 1029 | 1030 | CF$UID 1031 | 67 1032 | 1033 | 1034 | CF$UID 1035 | 68 1036 | 1037 | 1038 | NS.objects 1039 | 1040 | 1041 | CF$UID 1042 | 100 1043 | 1044 | 1045 | CF$UID 1046 | 101 1047 | 1048 | 1049 | 1050 | IDEUtilitiesArea 1051 | 260 1052 | 1053 | $class 1054 | 1055 | CF$UID 1056 | 60 1057 | 1058 | NS.keys 1059 | 1060 | 1061 | CF$UID 1062 | 103 1063 | 1064 | 1065 | CF$UID 1066 | 104 1067 | 1068 | 1069 | CF$UID 1070 | 105 1071 | 1072 | 1073 | CF$UID 1074 | 106 1075 | 1076 | 1077 | CF$UID 1078 | 107 1079 | 1080 | 1081 | CF$UID 1082 | 108 1083 | 1084 | 1085 | CF$UID 1086 | 109 1087 | 1088 | 1089 | CF$UID 1090 | 110 1091 | 1092 | 1093 | NS.objects 1094 | 1095 | 1096 | CF$UID 1097 | 13 1098 | 1099 | 1100 | CF$UID 1101 | 111 1102 | 1103 | 1104 | CF$UID 1105 | 154 1106 | 1107 | 1108 | CF$UID 1109 | 157 1110 | 1111 | 1112 | CF$UID 1113 | 162 1114 | 1115 | 1116 | CF$UID 1117 | 163 1118 | 1119 | 1120 | CF$UID 1121 | 13 1122 | 1123 | 1124 | CF$UID 1125 | 13 1126 | 1127 | 1128 | 1129 | BreakpointsActivated 1130 | DefaultEditorStatesForURLs 1131 | ActiveScheme 1132 | ActiveRunDestination 1133 | DocumentWindows 1134 | RecentEditorDocumentURLs 1135 | AppFocusInMiniDebugging 1136 | DebuggingWindowsLayerMode 1137 | 1138 | $class 1139 | 1140 | CF$UID 1141 | 60 1142 | 1143 | NS.keys 1144 | 1145 | 1146 | CF$UID 1147 | 112 1148 | 1149 | 1150 | CF$UID 1151 | 113 1152 | 1153 | 1154 | NS.objects 1155 | 1156 | 1157 | CF$UID 1158 | 114 1159 | 1160 | 1161 | CF$UID 1162 | 135 1163 | 1164 | 1165 | 1166 | Xcode.Xcode3ProjectSupport.EditorDocument.Xcode3Project 1167 | Xcode.IDEKit.EditorDocument.SourceCode 1168 | 1169 | $class 1170 | 1171 | CF$UID 1172 | 60 1173 | 1174 | NS.keys 1175 | 1176 | 1177 | CF$UID 1178 | 115 1179 | 1180 | 1181 | NS.objects 1182 | 1183 | 1184 | CF$UID 1185 | 118 1186 | 1187 | 1188 | 1189 | 1190 | $class 1191 | 1192 | CF$UID 1193 | 49 1194 | 1195 | NS.base 1196 | 1197 | CF$UID 1198 | 0 1199 | 1200 | NS.relative 1201 | 1202 | CF$UID 1203 | 116 1204 | 1205 | 1206 | 1207 | $class 1208 | 1209 | CF$UID 1210 | 117 1211 | 1212 | NS.string 1213 | file://localhost/Users/mikeash/Development/Projects/Public/ZeroingWeakRef/ZeroingWeakRef.xcodeproj/ 1214 | 1215 | 1216 | $classes 1217 | 1218 | NSMutableString 1219 | NSString 1220 | NSObject 1221 | 1222 | $classname 1223 | NSMutableString 1224 | 1225 | 1226 | $class 1227 | 1228 | CF$UID 1229 | 60 1230 | 1231 | NS.keys 1232 | 1233 | 1234 | CF$UID 1235 | 52 1236 | 1237 | 1238 | CF$UID 1239 | 119 1240 | 1241 | 1242 | NS.objects 1243 | 1244 | 1245 | CF$UID 1246 | 120 1247 | 1248 | 1249 | CF$UID 1250 | 129 1251 | 1252 | 1253 | 1254 | Xcode3ProjectEditor.sourceList.splitview 1255 | 1256 | $class 1257 | 1258 | CF$UID 1259 | 12 1260 | 1261 | NS.objects 1262 | 1263 | 1264 | CF$UID 1265 | 121 1266 | 1267 | 1268 | 1269 | 1270 | $class 1271 | 1272 | CF$UID 1273 | 128 1274 | 1275 | documentURL 1276 | 1277 | CF$UID 1278 | 122 1279 | 1280 | selection 1281 | 1282 | CF$UID 1283 | 124 1284 | 1285 | timestamp 1286 | 1287 | CF$UID 1288 | 123 1289 | 1290 | 1291 | file://localhost/Users/mikeash/Development/Projects/Public/ZeroingWeakRef/ZeroingWeakRef.xcodeproj/ 1292 | 300046470.80025101 1293 | 1294 | $class 1295 | 1296 | CF$UID 1297 | 60 1298 | 1299 | NS.keys 1300 | 1301 | 1302 | CF$UID 1303 | 125 1304 | 1305 | 1306 | CF$UID 1307 | 126 1308 | 1309 | 1310 | NS.objects 1311 | 1312 | 1313 | CF$UID 1314 | 45 1315 | 1316 | 1317 | CF$UID 1318 | 127 1319 | 1320 | 1321 | 1322 | Project 1323 | Editor 1324 | Xcode3ProjectInfoEditor 1325 | 1326 | $classes 1327 | 1328 | Xcode3ProjectDocumentLocation 1329 | DVTDocumentLocation 1330 | NSObject 1331 | 1332 | $classname 1333 | Xcode3ProjectDocumentLocation 1334 | 1335 | 1336 | $class 1337 | 1338 | CF$UID 1339 | 60 1340 | 1341 | NS.keys 1342 | 1343 | 1344 | CF$UID 1345 | 64 1346 | 1347 | 1348 | NS.objects 1349 | 1350 | 1351 | CF$UID 1352 | 130 1353 | 1354 | 1355 | 1356 | 1357 | $class 1358 | 1359 | CF$UID 1360 | 61 1361 | 1362 | NS.objects 1363 | 1364 | 1365 | CF$UID 1366 | 131 1367 | 1368 | 1369 | CF$UID 1370 | 133 1371 | 1372 | 1373 | 1374 | 1375 | $class 1376 | 1377 | CF$UID 1378 | 59 1379 | 1380 | NS.keys 1381 | 1382 | 1383 | CF$UID 1384 | 67 1385 | 1386 | 1387 | CF$UID 1388 | 68 1389 | 1390 | 1391 | NS.objects 1392 | 1393 | 1394 | CF$UID 1395 | 69 1396 | 1397 | 1398 | CF$UID 1399 | 132 1400 | 1401 | 1402 | 1403 | 162 1404 | 1405 | $class 1406 | 1407 | CF$UID 1408 | 59 1409 | 1410 | NS.keys 1411 | 1412 | 1413 | CF$UID 1414 | 67 1415 | 1416 | 1417 | CF$UID 1418 | 68 1419 | 1420 | 1421 | NS.objects 1422 | 1423 | 1424 | CF$UID 1425 | 69 1426 | 1427 | 1428 | CF$UID 1429 | 134 1430 | 1431 | 1432 | 1433 | 977 1434 | 1435 | $class 1436 | 1437 | CF$UID 1438 | 60 1439 | 1440 | NS.keys 1441 | 1442 | 1443 | CF$UID 1444 | 136 1445 | 1446 | 1447 | CF$UID 1448 | 138 1449 | 1450 | 1451 | NS.objects 1452 | 1453 | 1454 | CF$UID 1455 | 140 1456 | 1457 | 1458 | CF$UID 1459 | 148 1460 | 1461 | 1462 | 1463 | 1464 | $class 1465 | 1466 | CF$UID 1467 | 49 1468 | 1469 | NS.base 1470 | 1471 | CF$UID 1472 | 0 1473 | 1474 | NS.relative 1475 | 1476 | CF$UID 1477 | 137 1478 | 1479 | 1480 | 1481 | $class 1482 | 1483 | CF$UID 1484 | 117 1485 | 1486 | NS.string 1487 | file://localhost/Users/mikeash/Development/Projects/Public/ZeroingWeakRef/Source/MAZeroingWeakRef.m 1488 | 1489 | 1490 | $class 1491 | 1492 | CF$UID 1493 | 49 1494 | 1495 | NS.base 1496 | 1497 | CF$UID 1498 | 0 1499 | 1500 | NS.relative 1501 | 1502 | CF$UID 1503 | 139 1504 | 1505 | 1506 | 1507 | $class 1508 | 1509 | CF$UID 1510 | 117 1511 | 1512 | NS.string 1513 | file://localhost/var/folders/YT/YTiq3QDl2RW4ME+BYnLyRU+++TM/-Tmp-/___TERMINATING_DUE_TO_UNCAUGHT_EXCEPTION____disassembly_D1BF66C9-AF07-4742-9797-C6200CBBA557.s 1514 | 1515 | 1516 | $class 1517 | 1518 | CF$UID 1519 | 60 1520 | 1521 | NS.keys 1522 | 1523 | 1524 | CF$UID 1525 | 141 1526 | 1527 | 1528 | CF$UID 1529 | 142 1530 | 1531 | 1532 | NS.objects 1533 | 1534 | 1535 | CF$UID 1536 | 143 1537 | 1538 | 1539 | CF$UID 1540 | 147 1541 | 1542 | 1543 | 1544 | SelectedDocumentLocations 1545 | VisibleCharacterRange 1546 | 1547 | $class 1548 | 1549 | CF$UID 1550 | 12 1551 | 1552 | NS.objects 1553 | 1554 | 1555 | CF$UID 1556 | 144 1557 | 1558 | 1559 | 1560 | 1561 | $class 1562 | 1563 | CF$UID 1564 | 57 1565 | 1566 | characterRangeLen 1567 | 0 1568 | characterRangeLoc 1569 | 2440 1570 | documentURL 1571 | 1572 | CF$UID 1573 | 145 1574 | 1575 | endingColumnNumber 1576 | -1 1577 | endingLineNumber 1578 | -1 1579 | startingColumnNumber 1580 | -1 1581 | startingLineNumber 1582 | -1 1583 | timestamp 1584 | 1585 | CF$UID 1586 | 146 1587 | 1588 | 1589 | file://localhost/Users/mikeash/Development/Projects/Public/ZeroingWeakRef/Source/MAZeroingWeakRef.m 1590 | 300130779.24941701 1591 | {1559, 2347} 1592 | 1593 | $class 1594 | 1595 | CF$UID 1596 | 60 1597 | 1598 | NS.keys 1599 | 1600 | 1601 | CF$UID 1602 | 141 1603 | 1604 | 1605 | CF$UID 1606 | 142 1607 | 1608 | 1609 | NS.objects 1610 | 1611 | 1612 | CF$UID 1613 | 149 1614 | 1615 | 1616 | CF$UID 1617 | 153 1618 | 1619 | 1620 | 1621 | 1622 | $class 1623 | 1624 | CF$UID 1625 | 12 1626 | 1627 | NS.objects 1628 | 1629 | 1630 | CF$UID 1631 | 150 1632 | 1633 | 1634 | 1635 | 1636 | $class 1637 | 1638 | CF$UID 1639 | 57 1640 | 1641 | characterRangeLen 1642 | 0 1643 | characterRangeLoc 1644 | 0 1645 | documentURL 1646 | 1647 | CF$UID 1648 | 151 1649 | 1650 | endingColumnNumber 1651 | -1 1652 | endingLineNumber 1653 | -1 1654 | startingColumnNumber 1655 | -1 1656 | startingLineNumber 1657 | -1 1658 | timestamp 1659 | 1660 | CF$UID 1661 | 152 1662 | 1663 | 1664 | file://localhost/var/folders/YT/YTiq3QDl2RW4ME+BYnLyRU+++TM/-Tmp-/___TERMINATING_DUE_TO_UNCAUGHT_EXCEPTION____disassembly_D1BF66C9-AF07-4742-9797-C6200CBBA557.s 1665 | 300130777.00297701 1666 | {0, 438} 1667 | 1668 | $class 1669 | 1670 | CF$UID 1671 | 60 1672 | 1673 | NS.keys 1674 | 1675 | 1676 | CF$UID 1677 | 155 1678 | 1679 | 1680 | NS.objects 1681 | 1682 | 1683 | CF$UID 1684 | 156 1685 | 1686 | 1687 | 1688 | IDENameString 1689 | ZeroingWeakRef 1690 | 1691 | $class 1692 | 1693 | CF$UID 1694 | 60 1695 | 1696 | NS.keys 1697 | 1698 | 1699 | CF$UID 1700 | 158 1701 | 1702 | 1703 | CF$UID 1704 | 159 1705 | 1706 | 1707 | NS.objects 1708 | 1709 | 1710 | CF$UID 1711 | 160 1712 | 1713 | 1714 | CF$UID 1715 | 161 1716 | 1717 | 1718 | 1719 | IDEDeviceLocation 1720 | IDEDeviceArchitecture 1721 | dvtdevice-local-computer:localhost 1722 | i386 1723 | 1724 | $class 1725 | 1726 | CF$UID 1727 | 61 1728 | 1729 | NS.objects 1730 | 1731 | 1732 | 1733 | $class 1734 | 1735 | CF$UID 1736 | 61 1737 | 1738 | NS.objects 1739 | 1740 | 1741 | CF$UID 1742 | 164 1743 | 1744 | 1745 | CF$UID 1746 | 166 1747 | 1748 | 1749 | CF$UID 1750 | 167 1751 | 1752 | 1753 | CF$UID 1754 | 168 1755 | 1756 | 1757 | 1758 | 1759 | $class 1760 | 1761 | CF$UID 1762 | 49 1763 | 1764 | NS.base 1765 | 1766 | CF$UID 1767 | 0 1768 | 1769 | NS.relative 1770 | 1771 | CF$UID 1772 | 165 1773 | 1774 | 1775 | file://localhost/Users/mikeash/Development/Projects/Public/ZeroingWeakRef/Source/main.m 1776 | 1777 | $class 1778 | 1779 | CF$UID 1780 | 49 1781 | 1782 | NS.base 1783 | 1784 | CF$UID 1785 | 0 1786 | 1787 | NS.relative 1788 | 1789 | CF$UID 1790 | 145 1791 | 1792 | 1793 | 1794 | $class 1795 | 1796 | CF$UID 1797 | 49 1798 | 1799 | NS.base 1800 | 1801 | CF$UID 1802 | 0 1803 | 1804 | NS.relative 1805 | 1806 | CF$UID 1807 | 151 1808 | 1809 | 1810 | 1811 | $class 1812 | 1813 | CF$UID 1814 | 49 1815 | 1816 | NS.base 1817 | 1818 | CF$UID 1819 | 0 1820 | 1821 | NS.relative 1822 | 1823 | CF$UID 1824 | 122 1825 | 1826 | 1827 | 1828 | $class 1829 | 1830 | CF$UID 1831 | 60 1832 | 1833 | NS.keys 1834 | 1835 | 1836 | CF$UID 1837 | 170 1838 | 1839 | 1840 | CF$UID 1841 | 171 1842 | 1843 | 1844 | CF$UID 1845 | 172 1846 | 1847 | 1848 | CF$UID 1849 | 173 1850 | 1851 | 1852 | CF$UID 1853 | 10 1854 | 1855 | 1856 | NS.objects 1857 | 1858 | 1859 | CF$UID 1860 | 174 1861 | 1862 | 1863 | CF$UID 1864 | 13 1865 | 1866 | 1867 | CF$UID 1868 | 10 1869 | 1870 | 1871 | CF$UID 1872 | 175 1873 | 1874 | 1875 | CF$UID 1876 | 176 1877 | 1878 | 1879 | 1880 | IDEOrderedWorkspaceTabControllers 1881 | IDEUserWantsMiniDebuggingConsole 1882 | IDEActiveWorkspaceTabController 1883 | IDEWindowFrame 1884 | 1885 | $class 1886 | 1887 | CF$UID 1888 | 12 1889 | 1890 | NS.objects 1891 | 1892 | 1893 | CF$UID 1894 | 10 1895 | 1896 | 1897 | 1898 | {{264, 99}, {1400, 971}} 1899 | 1900 | $class 1901 | 1902 | CF$UID 1903 | 60 1904 | 1905 | NS.keys 1906 | 1907 | 1908 | CF$UID 1909 | 177 1910 | 1911 | 1912 | CF$UID 1913 | 178 1914 | 1915 | 1916 | CF$UID 1917 | 179 1918 | 1919 | 1920 | CF$UID 1921 | 180 1922 | 1923 | 1924 | CF$UID 1925 | 181 1926 | 1927 | 1928 | CF$UID 1929 | 182 1930 | 1931 | 1932 | CF$UID 1933 | 183 1934 | 1935 | 1936 | NS.objects 1937 | 1938 | 1939 | CF$UID 1940 | 184 1941 | 1942 | 1943 | CF$UID 1944 | 62 1945 | 1946 | 1947 | CF$UID 1948 | 185 1949 | 1950 | 1951 | CF$UID 1952 | 195 1953 | 1954 | 1955 | CF$UID 1956 | 220 1957 | 1958 | 1959 | CF$UID 1960 | 13 1961 | 1962 | 1963 | CF$UID 1964 | 229 1965 | 1966 | 1967 | 1968 | IDETabLabel 1969 | IDEShowNavigator 1970 | IDEWorkspaceTabControllerUtilityAreaSplitView 1971 | IDENavigatorArea 1972 | IDEWorkspaceTabControllerDesignAreaSplitView 1973 | IDEShowUtilities 1974 | IDEEditorArea 1975 | main.m 1976 | 1977 | $class 1978 | 1979 | CF$UID 1980 | 60 1981 | 1982 | NS.keys 1983 | 1984 | 1985 | CF$UID 1986 | 186 1987 | 1988 | 1989 | NS.objects 1990 | 1991 | 1992 | CF$UID 1993 | 187 1994 | 1995 | 1996 | 1997 | DVTSplitViewItems 1998 | 1999 | $class 2000 | 2001 | CF$UID 2002 | 61 2003 | 2004 | NS.objects 2005 | 2006 | 2007 | CF$UID 2008 | 188 2009 | 2010 | 2011 | CF$UID 2012 | 193 2013 | 2014 | 2015 | 2016 | 2017 | $class 2018 | 2019 | CF$UID 2020 | 59 2021 | 2022 | NS.keys 2023 | 2024 | 2025 | CF$UID 2026 | 189 2027 | 2028 | 2029 | CF$UID 2030 | 190 2031 | 2032 | 2033 | NS.objects 2034 | 2035 | 2036 | CF$UID 2037 | 191 2038 | 2039 | 2040 | CF$UID 2041 | 192 2042 | 2043 | 2044 | 2045 | DVTIdentifier 2046 | DVTViewMagnitude 2047 | 2048 | 660 2049 | 2050 | $class 2051 | 2052 | CF$UID 2053 | 59 2054 | 2055 | NS.keys 2056 | 2057 | 2058 | CF$UID 2059 | 189 2060 | 2061 | 2062 | CF$UID 2063 | 190 2064 | 2065 | 2066 | NS.objects 2067 | 2068 | 2069 | CF$UID 2070 | 191 2071 | 2072 | 2073 | CF$UID 2074 | 194 2075 | 2076 | 2077 | 2078 | 216 2079 | 2080 | $class 2081 | 2082 | CF$UID 2083 | 60 2084 | 2085 | NS.keys 2086 | 2087 | 2088 | CF$UID 2089 | 196 2090 | 2091 | 2092 | CF$UID 2093 | 197 2094 | 2095 | 2096 | CF$UID 2097 | 198 2098 | 2099 | 2100 | NS.objects 2101 | 2102 | 2103 | CF$UID 2104 | 199 2105 | 2106 | 2107 | CF$UID 2108 | 196 2109 | 2110 | 2111 | CF$UID 2112 | 204 2113 | 2114 | 2115 | 2116 | Xcode.DebuggerKit.ThreadsStacksNavigator 2117 | SelectedNavigator 2118 | Xcode.IDEKit.Navigator.Structure 2119 | 2120 | $class 2121 | 2122 | CF$UID 2123 | 60 2124 | 2125 | NS.keys 2126 | 2127 | 2128 | CF$UID 2129 | 200 2130 | 2131 | 2132 | CF$UID 2133 | 201 2134 | 2135 | 2136 | CF$UID 2137 | 202 2138 | 2139 | 2140 | NS.objects 2141 | 2142 | 2143 | CF$UID 2144 | 203 2145 | 2146 | 2147 | CF$UID 2148 | 13 2149 | 2150 | 2151 | CF$UID 2152 | 13 2153 | 2154 | 2155 | 2156 | IDEStackCompressionValue 2157 | IDEThreadsOrQueuesMode 2158 | IDEHideAncestorIfAllFramesHaveNoSymbols 2159 | 2 2160 | 2161 | $class 2162 | 2163 | CF$UID 2164 | 60 2165 | 2166 | NS.keys 2167 | 2168 | 2169 | CF$UID 2170 | 205 2171 | 2172 | 2173 | CF$UID 2174 | 206 2175 | 2176 | 2177 | CF$UID 2178 | 207 2179 | 2180 | 2181 | CF$UID 2182 | 208 2183 | 2184 | 2185 | CF$UID 2186 | 209 2187 | 2188 | 2189 | CF$UID 2190 | 210 2191 | 2192 | 2193 | NS.objects 2194 | 2195 | 2196 | CF$UID 2197 | 13 2198 | 2199 | 2200 | CF$UID 2201 | 211 2202 | 2203 | 2204 | CF$UID 2205 | 13 2206 | 2207 | 2208 | CF$UID 2209 | 13 2210 | 2211 | 2212 | CF$UID 2213 | 216 2214 | 2215 | 2216 | CF$UID 2217 | 219 2218 | 2219 | 2220 | 2221 | IDEUnsavedDocumentFilteringEnabled 2222 | IDEExpandedItems 2223 | IDERecentDocumentFilteringEnabled 2224 | IDESCMStatusFilteringEnabled 2225 | IDESelectedObjects 2226 | IDEVisibleRect 2227 | 2228 | $class 2229 | 2230 | CF$UID 2231 | 61 2232 | 2233 | NS.objects 2234 | 2235 | 2236 | CF$UID 2237 | 212 2238 | 2239 | 2240 | CF$UID 2241 | 215 2242 | 2243 | 2244 | 2245 | 2246 | $class 2247 | 2248 | CF$UID 2249 | 61 2250 | 2251 | NS.objects 2252 | 2253 | 2254 | CF$UID 2255 | 213 2256 | 2257 | 2258 | CF$UID 2259 | 214 2260 | 2261 | 2262 | 2263 | ZeroingWeakRef 2264 | Source 2265 | 2266 | $class 2267 | 2268 | CF$UID 2269 | 61 2270 | 2271 | NS.objects 2272 | 2273 | 2274 | CF$UID 2275 | 213 2276 | 2277 | 2278 | 2279 | 2280 | $class 2281 | 2282 | CF$UID 2283 | 61 2284 | 2285 | NS.objects 2286 | 2287 | 2288 | CF$UID 2289 | 217 2290 | 2291 | 2292 | 2293 | 2294 | $class 2295 | 2296 | CF$UID 2297 | 61 2298 | 2299 | NS.objects 2300 | 2301 | 2302 | CF$UID 2303 | 213 2304 | 2305 | 2306 | CF$UID 2307 | 214 2308 | 2309 | 2310 | CF$UID 2311 | 218 2312 | 2313 | 2314 | 2315 | main.m 2316 | {{0, 0}, {259, 832}} 2317 | 2318 | $class 2319 | 2320 | CF$UID 2321 | 60 2322 | 2323 | NS.keys 2324 | 2325 | 2326 | CF$UID 2327 | 186 2328 | 2329 | 2330 | NS.objects 2331 | 2332 | 2333 | CF$UID 2334 | 221 2335 | 2336 | 2337 | 2338 | 2339 | $class 2340 | 2341 | CF$UID 2342 | 61 2343 | 2344 | NS.objects 2345 | 2346 | 2347 | CF$UID 2348 | 222 2349 | 2350 | 2351 | CF$UID 2352 | 224 2353 | 2354 | 2355 | CF$UID 2356 | 226 2357 | 2358 | 2359 | 2360 | 2361 | $class 2362 | 2363 | CF$UID 2364 | 59 2365 | 2366 | NS.keys 2367 | 2368 | 2369 | CF$UID 2370 | 189 2371 | 2372 | 2373 | CF$UID 2374 | 190 2375 | 2376 | 2377 | NS.objects 2378 | 2379 | 2380 | CF$UID 2381 | 180 2382 | 2383 | 2384 | CF$UID 2385 | 223 2386 | 2387 | 2388 | 2389 | 260 2390 | 2391 | $class 2392 | 2393 | CF$UID 2394 | 59 2395 | 2396 | NS.keys 2397 | 2398 | 2399 | CF$UID 2400 | 189 2401 | 2402 | 2403 | CF$UID 2404 | 190 2405 | 2406 | 2407 | NS.objects 2408 | 2409 | 2410 | CF$UID 2411 | 183 2412 | 2413 | 2414 | CF$UID 2415 | 225 2416 | 2417 | 2418 | 2419 | 1140 2420 | 2421 | $class 2422 | 2423 | CF$UID 2424 | 59 2425 | 2426 | NS.keys 2427 | 2428 | 2429 | CF$UID 2430 | 189 2431 | 2432 | 2433 | CF$UID 2434 | 190 2435 | 2436 | 2437 | NS.objects 2438 | 2439 | 2440 | CF$UID 2441 | 227 2442 | 2443 | 2444 | CF$UID 2445 | 228 2446 | 2447 | 2448 | 2449 | IDEUtilitiesArea 2450 | 260 2451 | 2452 | $class 2453 | 2454 | CF$UID 2455 | 60 2456 | 2457 | NS.keys 2458 | 2459 | 2460 | CF$UID 2461 | 230 2462 | 2463 | 2464 | CF$UID 2465 | 231 2466 | 2467 | 2468 | CF$UID 2469 | 232 2470 | 2471 | 2472 | NS.objects 2473 | 2474 | 2475 | CF$UID 2476 | 13 2477 | 2478 | 2479 | CF$UID 2480 | 13 2481 | 2482 | 2483 | CF$UID 2484 | 233 2485 | 2486 | 2487 | 2488 | EditorMode 2489 | ShowDebuggerArea 2490 | IDEEditorMode_Standard 2491 | 2492 | $class 2493 | 2494 | CF$UID 2495 | 60 2496 | 2497 | NS.keys 2498 | 2499 | 2500 | CF$UID 2501 | 234 2502 | 2503 | 2504 | NS.objects 2505 | 2506 | 2507 | CF$UID 2508 | 235 2509 | 2510 | 2511 | 2512 | EditorStates 2513 | 2514 | $class 2515 | 2516 | CF$UID 2517 | 59 2518 | 2519 | NS.keys 2520 | 2521 | 2522 | CF$UID 2523 | 234 2524 | 2525 | 2526 | CF$UID 2527 | 236 2528 | 2529 | 2530 | NS.objects 2531 | 2532 | 2533 | CF$UID 2534 | 237 2535 | 2536 | 2537 | CF$UID 2538 | 13 2539 | 2540 | 2541 | 2542 | SelectedEditorState 2543 | 2544 | $class 2545 | 2546 | CF$UID 2547 | 61 2548 | 2549 | NS.objects 2550 | 2551 | 2552 | CF$UID 2553 | 238 2554 | 2555 | 2556 | 2557 | 2558 | $class 2559 | 2560 | CF$UID 2561 | 60 2562 | 2563 | NS.keys 2564 | 2565 | 2566 | CF$UID 2567 | 239 2568 | 2569 | 2570 | CF$UID 2571 | 240 2572 | 2573 | 2574 | CF$UID 2575 | 241 2576 | 2577 | 2578 | CF$UID 2579 | 242 2580 | 2581 | 2582 | CF$UID 2583 | 243 2584 | 2585 | 2586 | CF$UID 2587 | 244 2588 | 2589 | 2590 | NS.objects 2591 | 2592 | 2593 | CF$UID 2594 | 245 2595 | 2596 | 2597 | CF$UID 2598 | 250 2599 | 2600 | 2601 | CF$UID 2602 | 255 2603 | 2604 | 2605 | CF$UID 2606 | 257 2607 | 2608 | 2609 | CF$UID 2610 | 113 2611 | 2612 | 2613 | CF$UID 2614 | 258 2615 | 2616 | 2617 | 2618 | EditorState 2619 | ArchivableRepresentation 2620 | DocumentURL 2621 | FileDataType 2622 | DocumentExtensionIdentifier 2623 | HistoryMenuDescription 2624 | 2625 | $class 2626 | 2627 | CF$UID 2628 | 59 2629 | 2630 | NS.keys 2631 | 2632 | 2633 | CF$UID 2634 | 141 2635 | 2636 | 2637 | CF$UID 2638 | 142 2639 | 2640 | 2641 | NS.objects 2642 | 2643 | 2644 | CF$UID 2645 | 246 2646 | 2647 | 2648 | CF$UID 2649 | 249 2650 | 2651 | 2652 | 2653 | 2654 | $class 2655 | 2656 | CF$UID 2657 | 12 2658 | 2659 | NS.objects 2660 | 2661 | 2662 | CF$UID 2663 | 247 2664 | 2665 | 2666 | 2667 | 2668 | $class 2669 | 2670 | CF$UID 2671 | 57 2672 | 2673 | characterRangeLen 2674 | 0 2675 | characterRangeLoc 2676 | 1048 2677 | documentURL 2678 | 2679 | CF$UID 2680 | 165 2681 | 2682 | endingColumnNumber 2683 | -1 2684 | endingLineNumber 2685 | -1 2686 | startingColumnNumber 2687 | -1 2688 | startingLineNumber 2689 | -1 2690 | timestamp 2691 | 2692 | CF$UID 2693 | 248 2694 | 2695 | 2696 | 300136326.54178399 2697 | {0, 1170} 2698 | 2699 | $class 2700 | 2701 | CF$UID 2702 | 46 2703 | 2704 | DocumentLocation 2705 | 2706 | CF$UID 2707 | 254 2708 | 2709 | DomainIdentifier 2710 | 2711 | CF$UID 2712 | 251 2713 | 2714 | IdentifierPath 2715 | 2716 | CF$UID 2717 | 252 2718 | 2719 | 2720 | Xcode.IDENavigableItemDomain.WorkspaceStructure 2721 | 2722 | $class 2723 | 2724 | CF$UID 2725 | 12 2726 | 2727 | NS.objects 2728 | 2729 | 2730 | CF$UID 2731 | 218 2732 | 2733 | 2734 | CF$UID 2735 | 214 2736 | 2737 | 2738 | CF$UID 2739 | 253 2740 | 2741 | 2742 | 2743 | ZeroingWeakRef 2744 | $null 2745 | 2746 | $class 2747 | 2748 | CF$UID 2749 | 49 2750 | 2751 | NS.base 2752 | 2753 | CF$UID 2754 | 0 2755 | 2756 | NS.relative 2757 | 2758 | CF$UID 2759 | 256 2760 | 2761 | 2762 | file://localhost/Users/mikeash/Development/Projects/Public/ZeroingWeakRef/Source/main.m 2763 | public.objective-c-source 2764 | main() 2765 | 2766 | $top 2767 | 2768 | State 2769 | 2770 | CF$UID 2771 | 1 2772 | 2773 | 2774 | $version 2775 | 100000 2776 | 2777 | 2778 | -------------------------------------------------------------------------------- /ZeroingWeakRef_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'ZeroingWeakRef' target in the 'ZeroingWeakRef' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #endif 7 | 8 | --------------------------------------------------------------------------------