рдмрд╣реБрдд рд╕реЗ рд▓реЛрдЧ рд╢рд╛рдпрдж рдпрд╣ рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдЬрдм рдХреБрдВрдЬреА-рдореВрд▓реНрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдВрдкрддреНрддрд┐ рдкрд░рд┐рд╡рд░реНрддрди рдХреА рдШрдЯрдирд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрд╡реЗрджрди рдореЗрдВ "рдореГрдд" рд╡рд╕реНрддреБрдУрдВ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╣реБрдд рд╣реА рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рддрдВрддреНрд░ рд╣реИ, рдЬреЛ рдХреЙрд▓ рдкреНрд░рд╛рдкреНрддрдХрд░реНрддрд╛ рд╣реИрдВред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдмрд╣реБрдд рдкрд╣рд▓реЗ рдореГрдд рд╡рд╕реНрддреБ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ "рдиреЙрдХ рдбрд╛рдЙрди" рдХрд░рддреА рд╣реИ, рдЬрдм рдпрд╣ рдПрдХ рдШрдЯрдирд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреА рд╣реИ, рддреЛ рдпрд╣ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ рдЕрдм рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИ рдФрд░ рдпрд╣ рдХрд┐рд╕реА рднреА рддрд░реАрдХреЗ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред
рдпрджрд┐
NSKVODeallocateBreak
рдирд╛рдордХ рдбрд┐рдмрдЧрд┐рдВрдЧ рдореЗрдВ рдХрд┐рд╕реА рдЕрджреНрднреБрдд рдЪреАрдЬрд╝ рдХреЗ рд▓рд┐рдП рдРрд╕реА рд╡рд╕реНрддреБрдУрдВ рдХреА рдЦреЛрдЬ рдХрдард┐рди рдирд╣реАрдВ рд╣реИ, рддреЛ рдпрд╣ рдЖрдкрдХреЛ рдЙрд╕ рд╕рдордп рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдмрд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдЬрдм рдШрдЯрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рд╡рд╕реНрддреБ рдХреЛ рдЙрд╕рдХреЗ рдЬреАрд╡рдирдХрд╛рд▓ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдФрд░ рд╕рдорд╕реНрдпрд╛ рдХреЛ рджреВрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╖реНрдЯ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдШрдЯрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╡рд░реНрдЧ рдкрд░ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ, рдореИрдВ рдПрдХ рд╕рдорд╛рди рддрдВрддреНрд░ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рдШрдЯрдирд╛ рддрд░реНрдХ рдореЗрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рднрд╡рд┐рд╖реНрдпрд╡рд╛рдгреА рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ, рдФрд░ рдмреАрдорд╛ рдпрд╣рд╛рдВ рдЪреЛрдЯ рдирд╣реАрдВ рдкрд╣реБрдВрдЪрд╛рдПрдЧрд╛ред
рдпрд╣ рд▓реЗрдЦ рдЙрди рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рд╣реИ, рдЬрд┐рдирдХреЗ рдкрд╛рд╕ рдордВрдЪ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдЕрдиреБрднрд╡ рд╣реИ рдФрд░ рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдХрд┐рд╕реА рд╡рд╕реНрддреБ рдХрд╛ рдЬреАрд╡рди рдЪрдХреНрд░ рдХреИрд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдХреБрдЫ рдЕрдВрддрд░рд╛рд▓ рд╣реИрдВ (рдФрд░ рдореИрдВрдиреЗ рдмрд╛рд░-рдмрд╛рд░ рдЕрдиреБрднрд╡реА рдбреЗрд╡рд▓рдкрд░реНрд╕ рд╕реЗ рднреА рдореБрд▓рд╛рдХрд╛рдд рдХреА рд╣реИ, рдЬреЛ рдпрд╣ рдирд╣реАрдВ рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд▓рд┐рдВрдХ рдХрд╛рдЙрдВрдЯрд░ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдФрд░ рдХреМрди рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐
@synthesize
рд╕рд╛рдордиреЗ рдХреНрдпрд╛
@synthesize
), рддреЛ рдЖрдк
рдЗрд╕ рдореБрджреНрджреЗ рдкрд░ рд╢реЛрдз рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореЗрд░реЗ рдкреБрд░рд╛рдиреЗ рд▓реЗрдЦ рдХреЛ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ ред рдореИрдВ рджреВрд╕рд░реЛрдВ рд╕реЗ рдореЗрдЬ рдкрд░ рдкреВрдЫрддрд╛ рд╣реВрдВред
рддреЛ рд╣рдо рдХреНрдпрд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ? рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдЬреИрд╕реЗ рд╣реА
рдкрд┐рдЫрд▓реА рд░рд┐рд▓реАрдЬрд╝ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рддрдВрддреНрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдИрд╡реЗрдВрдЯ рдХреЛ рд╕рджрд╕реНрдпрддрд╛ рджреА рдЧрдИ рд╡рд╕реНрддреБ рдирд╖реНрдЯ рд╣реЛ рдЬрд╛рдП, рд╣рдореЗрдВ рдбрд┐рдмрдЧрд░ рдореЗрдВ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рд╣реЛред
рдЗрд╕рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ? рд╕реНрдкрд╖реНрдЯ рд╕рдорд╛рдзрд╛рди рдХрд┐рд╕реА рднреА рддрд░рд╣ рдХрд┐рд╕реА рдШрдЯрдирд╛ рдХреА рд╕рджрд╕реНрдпрддрд╛ рд▓реЗрддреЗ рд╕рдордп рд╣рд╕реНрддрд╛рдХреНрд╖рд░рдХрд░реНрддрд╛ рд╡рд╕реНрддреБ рдХреЗ
dealloc
рдХреЙрд▓ рдХреЛ рд░реЛрдХрдирд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдбреЗрд╡рд▓рдкрд░ рдХреЛ рд╕реВрдЪрд┐рдд рдХрд░рдирд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдпрд╣ рдмреБрд░реА рдХрд┐рд╕реНрдордд рд╣реИ - рдирд┐рдпрдорд┐рдд рд╕рд╛рдзрдиреЛрдВ (рдпрд╛, рдХрдо рд╕реЗ рдХрдо, рдореБрдЭреЗ рдРрд╕реА рд╡рд┐рдзрд┐ рдирд╣реАрдВ рдорд┐рд▓реА) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ
dealloc
рдХреЛ рд░реЛрдХрдирд╛ рдЕрд╕рдВрднрд╡ рд╣реИред
рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдСрдмреНрдЬреЗрдХреНрдЯрд┐рд╡-рд╕реА рдЗрд╕рдХреЗ рд░рдирдЯрд╛рдЗрдо рдХреЗ рд╕рд╛рде рдЗрд╕ рд╕реАрдорд╛ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдмрд╣реБрдд рд╕рдВрднрд╡ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рдореИрдВрдиреЗ
рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдХреЛрдбрд╢реИрдХрд░ рджреНрд╡рд╛рд░рд╛ рдиреЛрдЯ рдореЗрдВ рдЗрд╕ рд╕рдорд╛рдзрд╛рди рдХреЗ рд╡рд┐рдЪрд╛рд░ рдХреА рдЬрд╛рд╕реВрд╕реА рдХреА, рдФрд░ рдпрд╣ рдЕрд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рд░реВрдк рд╕реЗ рд╕реБрдВрджрд░ рдФрд░ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рдирд┐рдХрд▓рд╛ред рдЗрд╕реЗ рдЕрдкрдиреА рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП, рдореБрдЭреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдорд┐рд▓рд╛:
@interface NSObject (NSObjectDeallocInfo) -(void)dealloc_override; @end @implementation NSObject (NSObjectDeallocInfo) +(void)load { method_exchangeImplementations(class_getInstanceMethod(self, @selector(dealloc)), class_getInstanceMethod(self, @selector(dealloc_override))); } -(void)dealloc_override { [self dealloc_override]; } @end
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рдХреЛрдб рд╣рдорд╛рд░реЗ рдбреАрд▓рд▓реЛрдХ_рдУрд╡рд░рд╛рдЗрдб рд╣реИрдВрдбрд▓рд░ рдХреЗ рд╕рд╛рде рдбреАрд▓рд▓реЛрдХ рдореИрд╕реЗрдЬ рд╣реИрдВрдбрд▓рд░ рд╡рд┐рдзрд┐ рдХреА рдЬрдЧрд╣ рд▓реЗрддрд╛ рд╣реИ, рдФрд░ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдкреБрдирд░рд╛рд╡рд░реНрддреА рдХреЙрд▓
[self dealloc_override]
рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрдм рдорд╛рдирдХ рд╡рд┐рдзрд┐ рдХреА рдУрд░ рдЬрд╛рддрд╛ рд╣реИред
рджреВрд╕рд░рд╛ рд╕рд╡рд╛рд▓ рдпрд╣ рд╣реИ рдХрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ-рдИрд╡реЗрдВрдЯ рдХреЗ рд╕рд╛рде рд╣рдорд╛рд░реЗ рдСрдмреНрдЬреЗрдХреНрдЯ-рд╕рд┐рдЧреНрдирд░ рдХреЗ рдХрдиреЗрдХреНрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдХреИрд╕реЗ рд╕реНрдЯреЛрд░ рдХрд░реЗрдВред рдПрдХ рд╕реНрдерд┐рд░ рд╢рдмреНрджрдХреЛрд╢ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ? рдирд╣реАрдВ, рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдмрдврд╝ рд░рд╣реА рд╣реИред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рд░рдирдЯрд╛рдЗрдо рд╣рдореЗрдВ рдпрд╣рд╛рдВ рднреА рдорджрдж рдХрд░реЗрдЧрд╛ - рдпрд╣ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рд╡рд┐рд╕реНрддрд╛рд░ рдЧреБрдгреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╢рдмреНрджрдХреЛрд╢ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЙрджреНрджреЗрд╢реНрдп-рд╕реА рдореЗрдВ рдХрд┐рд╕реА рднреА рд╡рд╕реНрддреБ рдХреЗ рд╕рд╛рде рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ рдФрд░ рд╣рдореЗрдВ рдмрд╕ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рд╣рдорд╛рд░реА рд╕рдВрдкрддреНрддрд┐ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВред
static void* AW_EVENTHANDLER_KEY = (void *)0x2781;
рдЕрдм рдЗрд╕реЗ
NSObject
рдХреНрд▓рд╛рд╕ рдореЗрдВ
NSObject
, рдЙрд╕реА рд╢реНрд░реЗрдгреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЬрд┐рд╕реЗ рд╣рдордиреЗ рд╡рд┐рдзрд┐ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИред
@interface NSObject (NSObjectDeallocInfo) @property (nonatomic, assign) AWEventHandlersList *attachedEventHandler; -(void)dealloc_override; @end @implementation NSObject (NSObjectDeallocInfo) +(void)load { method_exchangeImplementations(class_getInstanceMethod(self, @selector(dealloc)), class_getInstanceMethod(self, @selector(dealloc_override))); } -(void)dealloc_override { [self dealloc_override]; } -(AWEventHandlersList *)attachedEventHandler { return (AWEventHandlersList *)objc_getAssociatedObject(self, AW_EVENTHANDLER_KEY); } -(void)setAttachedEventHandler:(AWEventHandlersList *)attachedEventHandler { objc_setAssociatedObject(self, AW_EVENTHANDLER_KEY, attachedEventHandler, OBJC_ASSOCIATION_ASSIGN); } @end
рдЕрдм рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд╕реНрддреБ
NSObject
рдкрд╛рд╕ рдПрдХ рд╡рд░реНрдЪреБрдЕрд▓ рдкреНрд░реЙрдкрд░реНрдЯреА
attachedEventHandler
NSObject
, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣рдо рдЕрдкрдиреА рдЬрд╝рд░реВрд░рдд рдХреА рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░реЗрдВрдЧреЗред
рд╣рдо
AWEventHandlersList
рд╡рд░реНрдЧ рдХреЗ рдХреЛрдб рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░реЗрдВрдЧреЗ
AWEventHandlersList
рдпрд╣ рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдмрд╛рдзреНрдп рдШрдЯрдирд╛ рдХреА рдПрдХ рд╡рд╕реНрддреБ
AWEventHandlersList
рдФрд░ рдПрдХ рдРрд╕реА рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝ рджреЗ рдЬреЛ рд╡рд╕реНрддреБ рдХреЛ рдШрдЯрдирд╛ рдХреЗ рд▓рд┐рдП рд╕рджрд╕реНрдпрддрд╛ рджреА рдЬрд╛рддреА рд╣реИред
-(void)addReceiver:(id)receiver delegate:(SEL)delegate { [self removeReceiver:receiver delegate:delegate]; [receiver setAttachedEventHandler:self]; [_handlers addObject:[AWEventHandler handlerWithTarget:receiver method:delegate]]; } -(void)removeReceiver:(id)receiver delegate:(SEL)delegate { [receiver setAttachedEventHandler:nil]; for(AWEventHandler *handler in [[_handlers copy] autorelease]) if(handler.method == delegate && handler.target == receiver) [_handlers removeObject:handler]; } -(BOOL)isReceiverInList:(id)receiver { for(AWEventHandler *handler in _handlers) if(handler.target == receiver) return YES; return NO; } -(void)clearReceivers { for(AWEventHandler *handler in _handlers) [handler.target setAttachedEventHandler:nil]; [_handlers removeAllObjects]; }
рдЕрдм рдпрд╣ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рд╕рд░рд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХреНрдпрд╛ рдерд╛ - рдЙрд╕ рд╕рдордп рдПрдХ рдЪреЗрдХ рдЬрд┐рд╕ рдкрд░ рд╡рд╕реНрддреБ рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
-(void)dealloc_override { AWEventHandlersList *handler = self.attachedEventHandler; if(handler) if([handler isReceiverInList:self]) { NSLog(@"Event handler (%@) target is released while subscribed", handler.name); [NSException raise:@"E_HANDLERRELEASED" format:@"Event handler (%@) target is released while subscribed", handler.name]; } [self dealloc_override]; }
рдЕрдм, рдпрджрд┐ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдирд╖реНрдЯ рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдЬрдм рдЗрд╕реЗ рдШрдЯрдирд╛ рдХреЗ рд▓рд┐рдП рд╕рджрд╕реНрдпрддрд╛ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рддреЛ рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рд╕рдмрд╕реЗ рдЕрдЪреНрдЫреА рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдЕрдкрд╡рд╛рдж рдХреЛ рдЙрд╕ рд╕реНрдерд╛рди рдкрд░ рдлреЗрдВрдХ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рд╡рд┐рдзреНрд╡рдВрд╕рдХ рдЯреНрд░рд┐рдЧрд░ рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ рдЖрдкрдХреЛ рдХреНрд░реИрд╢ рд░рд┐рдкреЛрд░реНрдЯ рдореЗрдВ рддреНрд░реБрдЯрд┐ рд╕реНрдЯреИрдХ рджреЗрдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдХреЗрд╡рд▓ 15 рдорд┐рдирдЯ рдореЗрдВ, рд╣рдордиреЗ рдЕрдкрдиреЗ рдбрд┐рдмрдЧрд┐рдВрдЧ рдЬреАрд╡рди рдХреЛ рдереЛрдбрд╝рд╛ рдЖрд╕рд╛рди рдмрдирд╛ рджрд┐рдпрд╛ рд╣реИред