Ссылка на себя внутри блока IPhone SDK
Я пытаюсь внедрить механизм обратного вызова, когда я передаю блок инициализации класса, и после некоторой работы этот класс перезванивает мне. Блок вызывается, и почти все работает, за исключением случаев, когда я вызываю что-либо на "себя" внутри блока. Я получаю сигнал, полученный Программой: "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 ответ
Во-первых, что такое blockSelf
в вашем коде?
Во-вторых, нет, нет причин, по которым вы не можете использовать self
и это свидетельствует об ошибке в вашем коде.
В частности, вы не копируете блок. Блоки начинаются в стеке. Таким образом, когда вы говорите, theCallback = aCallback;
вы храните ссылку на структуру данных в стеке. Как только определяющий кадр стека исчезает, эта структура больше не действительна.
+ Изменить theCallback = aCallback;
в theCallback = [aCallback copy];
(и добавить [theCallback release];
на ваш -dealloc
метод).