1/* 2 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 3 * Copyright (C) 2006 David Smith (catfish.man@gmail.com) 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 15 * its contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#import "WebDelegateImplementationCaching.h" 31 32#import "WebKitLogging.h" 33#import "WebView.h" 34#import "WebViewData.h" 35#import <objc/objc-runtime.h> 36 37@implementation WebView (WebDelegateImplementationCaching) 38 39WebResourceDelegateImplementationCache* WebViewGetResourceLoadDelegateImplementations(WebView *webView) 40{ 41 static WebResourceDelegateImplementationCache empty; 42 if (!webView) 43 return ∅ 44 return &webView->_private->resourceLoadDelegateImplementations; 45} 46 47WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementations(WebView *webView) 48{ 49 static WebFrameLoadDelegateImplementationCache empty; 50 if (!webView) 51 return ∅ 52 return &webView->_private->frameLoadDelegateImplementations; 53} 54 55WebScriptDebugDelegateImplementationCache* WebViewGetScriptDebugDelegateImplementations(WebView *webView) 56{ 57 static WebScriptDebugDelegateImplementationCache empty; 58 if (!webView) 59 return ∅ 60 return &webView->_private->scriptDebugDelegateImplementations; 61} 62 63// We use these functions to call the delegates and block exceptions. These functions are 64// declared inside a WebView category to get direct access to the delegate data memebers, 65// preventing more ObjC message dispatch and compensating for the expense of the @try/@catch. 66 67typedef float (*ObjCMsgSendFPRet)(id, SEL, ...); 68#if defined(__i386__) 69static const ObjCMsgSendFPRet objc_msgSend_float_return = reinterpret_cast<ObjCMsgSendFPRet>(objc_msgSend_fpret); 70#else 71static const ObjCMsgSendFPRet objc_msgSend_float_return = reinterpret_cast<ObjCMsgSendFPRet>(objc_msgSend); 72#endif 73 74static inline id CallDelegate(WebView *self, id delegate, SEL selector) 75{ 76 if (!delegate || ![delegate respondsToSelector:selector]) 77 return nil; 78 if (!self->_private->catchesDelegateExceptions) 79 return objc_msgSend(delegate, selector, self); 80 @try { 81 return objc_msgSend(delegate, selector, self); 82 } @catch(id exception) { 83 ReportDiscardedDelegateException(selector, exception); 84 } 85 return nil; 86} 87 88static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object) 89{ 90 if (!delegate || ![delegate respondsToSelector:selector]) 91 return nil; 92 if (!self->_private->catchesDelegateExceptions) 93 return objc_msgSend(delegate, selector, self, object); 94 @try { 95 return objc_msgSend(delegate, selector, self, object); 96 } @catch(id exception) { 97 ReportDiscardedDelegateException(selector, exception); 98 } 99 return nil; 100} 101 102static inline id CallDelegate(WebView *self, id delegate, SEL selector, NSRect rect) 103{ 104 if (!delegate || ![delegate respondsToSelector:selector]) 105 return nil; 106 if (!self->_private->catchesDelegateExceptions) 107 return reinterpret_cast<id (*)(id, SEL, WebView *, NSRect)>(objc_msgSend)(delegate, selector, self, rect); 108 @try { 109 return reinterpret_cast<id (*)(id, SEL, WebView *, NSRect)>(objc_msgSend)(delegate, selector, self, rect); 110 } @catch(id exception) { 111 ReportDiscardedDelegateException(selector, exception); 112 } 113 return nil; 114} 115 116static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object1, id object2) 117{ 118 if (!delegate || ![delegate respondsToSelector:selector]) 119 return nil; 120 if (!self->_private->catchesDelegateExceptions) 121 return objc_msgSend(delegate, selector, self, object1, object2); 122 @try { 123 return objc_msgSend(delegate, selector, self, object1, object2); 124 } @catch(id exception) { 125 ReportDiscardedDelegateException(selector, exception); 126 } 127 return nil; 128} 129 130static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object, BOOL boolean) 131{ 132 if (!delegate || ![delegate respondsToSelector:selector]) 133 return nil; 134 if (!self->_private->catchesDelegateExceptions) 135 return objc_msgSend(delegate, selector, self, object, boolean); 136 @try { 137 return objc_msgSend(delegate, selector, self, object, boolean); 138 } @catch(id exception) { 139 ReportDiscardedDelegateException(selector, exception); 140 } 141 return nil; 142} 143 144static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object1, id object2, id object3) 145{ 146 if (!delegate || ![delegate respondsToSelector:selector]) 147 return nil; 148 if (!self->_private->catchesDelegateExceptions) 149 return objc_msgSend(delegate, selector, self, object1, object2, object3); 150 @try { 151 return objc_msgSend(delegate, selector, self, object1, object2, object3); 152 } @catch(id exception) { 153 ReportDiscardedDelegateException(selector, exception); 154 } 155 return nil; 156} 157 158static inline id CallDelegate(WebView *self, id delegate, SEL selector, id object, NSUInteger integer) 159{ 160 if (!delegate || ![delegate respondsToSelector:selector]) 161 return nil; 162 if (!self->_private->catchesDelegateExceptions) 163 return objc_msgSend(delegate, selector, self, object, integer); 164 @try { 165 return objc_msgSend(delegate, selector, self, object, integer); 166 } @catch(id exception) { 167 ReportDiscardedDelegateException(selector, exception); 168 } 169 return nil; 170} 171 172static inline float CallDelegateReturningFloat(WebView *self, id delegate, SEL selector) 173{ 174 if (!delegate || ![delegate respondsToSelector:selector]) 175 return 0.0f; 176 if (!self->_private->catchesDelegateExceptions) 177 return objc_msgSend_float_return(delegate, selector, self); 178 @try { 179 return objc_msgSend_float_return(delegate, selector, self); 180 } @catch(id exception) { 181 ReportDiscardedDelegateException(selector, exception); 182 } 183 return 0.0f; 184} 185 186static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector) 187{ 188 if (!delegate || ![delegate respondsToSelector:selector]) 189 return result; 190 if (!self->_private->catchesDelegateExceptions) 191 return reinterpret_cast<BOOL (*)(id, SEL, WebView *)>(objc_msgSend)(delegate, selector, self); 192 @try { 193 return reinterpret_cast<BOOL (*)(id, SEL, WebView *)>(objc_msgSend)(delegate, selector, self); 194 } @catch(id exception) { 195 ReportDiscardedDelegateException(selector, exception); 196 } 197 return result; 198} 199 200static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object) 201{ 202 if (!delegate || ![delegate respondsToSelector:selector]) 203 return result; 204 if (!self->_private->catchesDelegateExceptions) 205 return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id)>(objc_msgSend)(delegate, selector, self, object); 206 @try { 207 return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id)>(objc_msgSend)(delegate, selector, self, object); 208 } @catch(id exception) { 209 ReportDiscardedDelegateException(selector, exception); 210 } 211 return result; 212} 213 214static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object, BOOL boolean) 215{ 216 if (!delegate || ![delegate respondsToSelector:selector]) 217 return result; 218 if (!self->_private->catchesDelegateExceptions) 219 return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, BOOL)>(objc_msgSend)(delegate, selector, self, object, boolean); 220 @try { 221 return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, BOOL)>(objc_msgSend)(delegate, selector, self, object, boolean); 222 } @catch(id exception) { 223 ReportDiscardedDelegateException(selector, exception); 224 } 225 return result; 226} 227 228static inline BOOL CallDelegateReturningBoolean(BOOL result, WebView *self, id delegate, SEL selector, id object1, id object2) 229{ 230 if (!delegate || ![delegate respondsToSelector:selector]) 231 return result; 232 if (!self->_private->catchesDelegateExceptions) 233 return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, id)>(objc_msgSend)(delegate, selector, self, object1, object2); 234 @try { 235 return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, id)>(objc_msgSend)(delegate, selector, self, object1, object2); 236 } @catch(id exception) { 237 ReportDiscardedDelegateException(selector, exception); 238 } 239 return result; 240} 241 242static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector) 243{ 244 if (!delegate) 245 return nil; 246 if (!self->_private->catchesDelegateExceptions) 247 return implementation(delegate, selector, self); 248 @try { 249 return implementation(delegate, selector, self); 250 } @catch(id exception) { 251 ReportDiscardedDelegateException(selector, exception); 252 } 253 return nil; 254} 255 256static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object) 257{ 258 if (!delegate) 259 return nil; 260 if (!self->_private->catchesDelegateExceptions) 261 return implementation(delegate, selector, self, object); 262 @try { 263 return implementation(delegate, selector, self, object); 264 } @catch(id exception) { 265 ReportDiscardedDelegateException(selector, exception); 266 } 267 return nil; 268} 269 270static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2) 271{ 272 if (!delegate) 273 return nil; 274 if (!self->_private->catchesDelegateExceptions) 275 return implementation(delegate, selector, self, object1, object2); 276 @try { 277 return implementation(delegate, selector, self, object1, object2); 278 } @catch(id exception) { 279 ReportDiscardedDelegateException(selector, exception); 280 } 281 return nil; 282} 283 284static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, id object3) 285{ 286 if (!delegate) 287 return nil; 288 if (!self->_private->catchesDelegateExceptions) 289 return implementation(delegate, selector, self, object1, object2, object3); 290 @try { 291 return implementation(delegate, selector, self, object1, object2, object3); 292 } @catch(id exception) { 293 ReportDiscardedDelegateException(selector, exception); 294 } 295 return nil; 296} 297 298static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, id object3, id object4) 299{ 300 if (!delegate) 301 return nil; 302 if (!self->_private->catchesDelegateExceptions) 303 return implementation(delegate, selector, self, object1, object2, object3, object4); 304 @try { 305 return implementation(delegate, selector, self, object1, object2, object3, object4); 306 } @catch(id exception) { 307 ReportDiscardedDelegateException(selector, exception); 308 } 309 return nil; 310} 311 312static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer, id object2) 313{ 314 if (!delegate) 315 return nil; 316 if (!self->_private->catchesDelegateExceptions) 317 return implementation(delegate, selector, self, object1, integer, object2); 318 @try { 319 return implementation(delegate, selector, self, object1, integer, object2); 320 } @catch(id exception) { 321 ReportDiscardedDelegateException(selector, exception); 322 } 323 return nil; 324} 325 326static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer1, NSInteger integer2, id object2) 327{ 328 if (!delegate) 329 return nil; 330 if (!self->_private->catchesDelegateExceptions) 331 return implementation(delegate, selector, self, object1, integer1, integer2, object2); 332 @try { 333 return implementation(delegate, selector, self, object1, integer1, integer2, object2); 334 } @catch(id exception) { 335 ReportDiscardedDelegateException(selector, exception); 336 } 337 return nil; 338} 339 340static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, id object2, NSInteger integer, id object3) 341{ 342 if (!delegate) 343 return nil; 344 if (!self->_private->catchesDelegateExceptions) 345 return implementation(delegate, selector, self, object1, object2, integer, object3); 346 @try { 347 return implementation(delegate, selector, self, object1, object2, integer, object3); 348 } @catch(id exception) { 349 ReportDiscardedDelegateException(selector, exception); 350 } 351 return nil; 352} 353 354static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer1, id object2, NSInteger integer2, id object3) 355{ 356 if (!delegate) 357 return nil; 358 if (!self->_private->catchesDelegateExceptions) 359 return implementation(delegate, selector, self, object1, integer1, object2, integer2, object3); 360 @try { 361 return implementation(delegate, selector, self, object1, integer1, object2, integer2, object3); 362 } @catch(id exception) { 363 ReportDiscardedDelegateException(selector, exception); 364 } 365 return nil; 366} 367 368static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSInteger integer, id object2, id object3, id object4) 369{ 370 if (!delegate) 371 return nil; 372 if (!self->_private->catchesDelegateExceptions) 373 return implementation(delegate, selector, self, object1, integer, object2, object3, object4); 374 @try { 375 return implementation(delegate, selector, self, object1, integer, object2, object3, object4); 376 } @catch(id exception) { 377 ReportDiscardedDelegateException(selector, exception); 378 } 379 return nil; 380} 381 382static inline id CallDelegate(IMP implementation, WebView *self, id delegate, SEL selector, id object1, NSTimeInterval interval, id object2, id object3) 383{ 384 if (!delegate) 385 return nil; 386 if (!self->_private->catchesDelegateExceptions) 387 return implementation(delegate, selector, self, object1, interval, object2, object3); 388 @try { 389 return implementation(delegate, selector, self, object1, interval, object2, object3); 390 } @catch(id exception) { 391 ReportDiscardedDelegateException(selector, exception); 392 } 393 return nil; 394} 395 396id CallUIDelegate(WebView *self, SEL selector) 397{ 398 return CallDelegate(self, self->_private->UIDelegate, selector); 399} 400 401id CallUIDelegate(WebView *self, SEL selector, id object) 402{ 403 return CallDelegate(self, self->_private->UIDelegate, selector, object); 404} 405 406id CallUIDelegate(WebView *self, SEL selector, id object, BOOL boolean) 407{ 408 return CallDelegate(self, self->_private->UIDelegate, selector, object, boolean); 409} 410 411id CallUIDelegate(WebView *self, SEL selector, NSRect rect) 412{ 413 return CallDelegate(self, self->_private->UIDelegate, selector, rect); 414} 415 416id CallUIDelegate(WebView *self, SEL selector, id object1, id object2) 417{ 418 return CallDelegate(self, self->_private->UIDelegate, selector, object1, object2); 419} 420 421id CallUIDelegate(WebView *self, SEL selector, id object1, id object2, id object3) 422{ 423 return CallDelegate(self, self->_private->UIDelegate, selector, object1, object2, object3); 424} 425 426id CallUIDelegate(WebView *self, SEL selector, id object, NSUInteger integer) 427{ 428 return CallDelegate(self, self->_private->UIDelegate, selector, object, integer); 429} 430 431float CallUIDelegateReturningFloat(WebView *self, SEL selector) 432{ 433 return CallDelegateReturningFloat(self, self->_private->UIDelegate, selector); 434} 435 436BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector) 437{ 438 return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector); 439} 440 441BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object) 442{ 443 return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object); 444} 445 446BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object, BOOL boolean) 447{ 448 return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object, boolean); 449} 450 451BOOL CallUIDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object1, id object2) 452{ 453 return CallDelegateReturningBoolean(result, self, self->_private->UIDelegate, selector, object1, object2); 454} 455 456id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector) 457{ 458 return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector); 459} 460 461id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object) 462{ 463 return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object); 464} 465 466id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2) 467{ 468 return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, object2); 469} 470 471id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3) 472{ 473 return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, object2, object3); 474} 475 476id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3, id object4) 477{ 478 return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, object2, object3, object4); 479} 480 481id CallFrameLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSTimeInterval interval, id object2, id object3) 482{ 483 return CallDelegate(implementation, self, self->_private->frameLoadDelegate, selector, object1, interval, object2, object3); 484} 485 486id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2) 487{ 488 return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2); 489} 490 491id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3) 492{ 493 return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, object3); 494} 495 496id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, id object3, id object4) 497{ 498 return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, object3, object4); 499} 500 501id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer, id object2) 502{ 503 return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, integer, object2); 504} 505 506id CallResourceLoadDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, NSInteger integer, id object3) 507{ 508 return CallDelegate(implementation, self, self->_private->resourceProgressDelegate, selector, object1, object2, integer, object3); 509} 510 511BOOL CallResourceLoadDelegateReturningBoolean(BOOL result, IMP implementation, WebView *self, SEL selector, id object1, id object2) 512{ 513 if (!self->_private->catchesDelegateExceptions) 514 return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, id)>(objc_msgSend)(self->_private->resourceProgressDelegate, selector, self, object1, object2); 515 @try { 516 return reinterpret_cast<BOOL (*)(id, SEL, WebView *, id, id)>(objc_msgSend)(self->_private->resourceProgressDelegate, selector, self, object1, object2); 517 } @catch(id exception) { 518 ReportDiscardedDelegateException(selector, exception); 519 } 520 return result; 521} 522 523id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, id object2, NSInteger integer, id object3) 524{ 525 return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, object2, integer, object3); 526} 527 528id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer1, id object2, NSInteger integer2, id object3) 529{ 530 return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer1, object2, integer2, object3); 531} 532 533id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer, id object2, id object3, id object4) 534{ 535 return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer, object2, object3, object4); 536} 537 538id CallScriptDebugDelegate(IMP implementation, WebView *self, SEL selector, id object1, NSInteger integer1, NSInteger integer2, id object2) 539{ 540 return CallDelegate(implementation, self, self->_private->scriptDebugDelegate, selector, object1, integer1, integer2, object2); 541} 542 543// The form delegate needs to have it's own implementation, because the first argument is never the WebView 544 545id CallFormDelegate(WebView *self, SEL selector, id object1, id object2) 546{ 547 id delegate = self->_private->formDelegate; 548 if (!delegate || ![delegate respondsToSelector:selector]) 549 return nil; 550 if (!self->_private->catchesDelegateExceptions) 551 return objc_msgSend(delegate, selector, object1, object2); 552 @try { 553 return objc_msgSend(delegate, selector, object1, object2); 554 } @catch(id exception) { 555 ReportDiscardedDelegateException(selector, exception); 556 } 557 return nil; 558} 559 560id CallFormDelegate(WebView *self, SEL selector, id object1, id object2, id object3, id object4, id object5) 561{ 562 id delegate = self->_private->formDelegate; 563 if (!delegate || ![delegate respondsToSelector:selector]) 564 return nil; 565 if (!self->_private->catchesDelegateExceptions) 566 return objc_msgSend(delegate, selector, object1, object2, object3, object4, object5); 567 @try { 568 return objc_msgSend(delegate, selector, object1, object2, object3, object4, object5); 569 } @catch(id exception) { 570 ReportDiscardedDelegateException(selector, exception); 571 } 572 return nil; 573} 574 575BOOL CallFormDelegateReturningBoolean(BOOL result, WebView *self, SEL selector, id object1, SEL selectorArg, id object2) 576{ 577 id delegate = self->_private->formDelegate; 578 if (!delegate || ![delegate respondsToSelector:selector]) 579 return result; 580 if (!self->_private->catchesDelegateExceptions) 581 return reinterpret_cast<BOOL (*)(id, SEL, id, SEL, id)>(objc_msgSend)(delegate, selector, object1, selectorArg, object2); 582 @try { 583 return reinterpret_cast<BOOL (*)(id, SEL, id, SEL, id)>(objc_msgSend)(delegate, selector, object1, selectorArg, object2); 584 } @catch(id exception) { 585 ReportDiscardedDelegateException(selector, exception); 586 } 587 return result; 588} 589 590@end 591