Непосредственно инициализированный делегат генерирует предупреждение ARC и сбой EXC_BAD_ACCESS

Я создал объект делегата, реализующий UITextFieldDelegateв своем собственном классе с именем NumericTextFieldDelegate, затем я инициализировал делегата в своем контроллере следующим образом:

textFieldName.delegate = [NumericTextFieldDelegate new];

И я получил это предупреждение от компилятора :

Assigning retained object to unsafe property; object will be released after assignment

Это означает, что объект будет освобожден после назначения, и на самом деле, когда я запускаю приложение и фокусирую UITextField, я получаю EXC_BAD_ACCESSи сбой приложения...

Единственный способ заставить это работать, который я нашел, - это создать статическую переменную с фабричным методом, который отправляет экземпляр NumericTextFieldDelegate:

@interface NumericTextFieldDelegate : NSObject 

+(NumericTextFieldDelegate *) getDelegate;

@end

@implementation NumericTextFieldDelegate

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {

    NSString *resultingString = [textField.text stringByReplacingCharactersInRange: range withString: string];

    // This allows backspace
    if ([resultingString length] == 0) {
        return true;
    }

    NSInteger holder;
    NSScanner *scan = [NSScanner scannerWithString: resultingString];

    return [scan scanInteger: &holder] && [scan isAtEnd];
}

+(NumericTextFieldDelegate *) getDelegate {
    static NumericTextFieldDelegate *del;
    @synchronized(del) {
        if(del == nil)
            del = [NumericTextFieldDelegate new];
    }
    return del;
}

@end

И затем, когда я назначаю делегат таким образом:

textFieldName.delegate = [NumericTextFieldDelegate getDelegate];

все работает Что ж , но мой вопрос:

Почему я не могу просто назначить анонимный новый экземпляр класса? Почему объект автоматически освобождается после присваивания?

Зачем мне нужен этот обходной путь?

Спасибо.

6
задан aleroot 31 May 2012 в 16:09
поделиться