ссылка на себя внутри блока IPhone SDK - PullRequest
1 голос
/ 02 июля 2010

Я пытаюсь внедрить механизм обратного вызова, в котором я передаю блок инициату класса, и после некоторой работы этот класс перезванивает мне.Блок вызывается, и почти все работает, за исключением случаев, когда я вызываю что-либо на «себя» внутри блока.Я получаю сигнал, полученный Программой: «EXC_BAD_ACCESS», если я не закомментирую какую-либо ссылку на себя в блоке.

Не ошибаюсь ли я, что могу получить доступ к себе внутри блока?Любой совет будет принята с благодарностью.Этот код находится в совершенно новом «Универсальном приложении», и в настоящее время я работаю над частью IPad, поэтому работаю под имитатором IPad.

Некоторый код:

__block LoginViewController *blockSelf = self;
    LoginAlertView *alert = [[LoginAlertView alloc] 
                         intWithPinPrompt:NO 
                         title:@"Mobile Login"
                         myCallback:^(LoginAlertView *v){
                             DLog(@"self %@", blockSelf);
                             NSString *u = v.userNameText;
                             NSString *p = v.passwordText;
                             NSString *i = v.pinText;
                             [self authenticateUser:u
                                           password:p
                                                pin:i];
                         }];

и вотнекоторый код из LoginAlertView

- (id) intWithPinPrompt:(BOOL)pinPromptEnabled title:(NSString*)aTitle myCallback:(loginClicked)aCallback{
if (self = [self initWithTitle:aTitle
                       message:nil 
                      delegate:self 
             cancelButtonTitle:@"Cancel" 
             otherButtonTitles:@"Login", nil]) {
    hasPinPrompt = pinPromptEnabled;
    theCallback = aCallback;
}
return self;
}

и обратный вызов

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (theCallback) {
    theCallback(self);
}
}

Я изменил следующую строку кода

theCallback = aCallback;

на

theCallback = [aCallback copy];

, который представляет мне следующую ошибку

Program received signal:  “EXC_BAD_ACCESS”.
(gdb) bt
#0  0x029c8c97 in objc_msgSend ()
#1  0xbfffe560 in ?? ()
#2  0x00026f66 in -[LoginViewController show] (self=0x4a38450, _cmd=0x209c36c) at LoginViewController.m:18
#3  0x00026d3b in -[AuthenticatedViewController viewWillAppear:] (self=0x4c1fac0, _cmd=0x20b59ac, animated=0 '\0') at AuthenticatedViewController.m:17

и еще одна вещь, определение моего блока выглядит так

typedef void(^loginClicked)(LoginAlertView*);

и переменная-член это

loginClicked theCallback;

также попытался переместить объявление блока в переменную и передать его. Это дало те же результаты. Каждый раз, когда я использую «копию» в боксе, я получаю страшный сигнал, полученный программой: «EXC_BAD_ACCESS»».Я подумал, что это может быть IOS3.2, поэтому я попытался запустить его под симулятором IPhone 4.0, те же результаты.Возможно ли выполнить настройку компилятора, чтобы «скопировать» блок в кучу?Я использую LLVM1.5

1 Ответ

4 голосов
/ 02 июля 2010

Во-первых, что такое blockSelf в вашем коде?

Во-вторых, нет, нет причины, по которой вы не можете использовать self, и это свидетельствует об ошибке в вашем коде.

В частности, вы не копируете блок.Блоки начинаются в стеке.Таким образом, когда вы говорите theCallback = aCallback;, вы сохраняете ссылку на структуру данных в стеке.Как только определяющий кадр стека исчезнет, ​​эта структура больше не будет действительной.

Измените theCallback = aCallback; на theCallback = [aCallback copy]; (и добавьте [theCallback release]; к своему -dealloc методу).

...