I agree with the analysis of @Inaziger. The delegate of the UITextField instance is a kind of weak link. It does not contain a delegate assigned to it. According to the ARC, the delegate will be nobody, no one keeps a link to it. Therefore, it will be up to the appointment to save it so that the delegate is called. You will copy the previous workaround like this:
- (void) somemethod { ... id<UITextFieldDelegate> tempDelegate = [NumericTextFieldDelegate new]; textFieldName.delegate = tempDelegate; ... }
the textFieldName instance received a link to a delegate created locally in some form. ARC will set temDelegate to zero after calling the method. However, the text field delegate still contains a pointer to the assigned memory, which is subsequently released by ARC. This is why you are facing a bad memory access failure.
By saving del as a static var in your class, it will be stored during the application launch cycle, unless you set it to nil. I think it's better to keep static del as a member of the class and provide a setter so you don't forget to release it. Sort of:
// in interface definition +(NumericTextFieldDelegate *) getDelegate; +(void) setDelegate:(id)newDel; // in implementation static NumericTextFieldDelegate* del; +(NumericTextFieldDelegate *) getDelegate { @synchronized(del) { if(del == nil) del = [NumericTextFieldDelegate new]; } return del; } +(void) setDelegate:(id)newDel { del = newDel; }
By the way, you can also save your previous bypass codes as they are. You can save the delegate in the text field class as a variable or class property.
@interface myTextFieldContainer () { @proerpty (strong) id<UITextFieldDelegate> delHolder; ... } @implementaion myTextFieldContainer { @sythysis delHolder = _delHodler; ... self.delHolder = [NumericTextFieldDelegate new]; textFieldName.delegate = self.delHolder;
The advantage of the above strategy is that you will not worry about freeing the delegate when your view controller is gone.
source share