Сообщение, отправленное в освобожденный экземпляр на UIButton внутри iCarousel

#ios #objective-c #uibutton #uigesturerecognizer #icarousel

#iOS #objective-c #уибуттон #uigesturerecognizer #icarousel #uibutton

Вопрос:

Я внедрил iCarousel (https://github.com/nicklockwood/iCarousel ) в мой проект Xcode, и теперь у меня есть прокручивающаяся карусель просмотров. Внутри каждого представления у меня есть UIButton, к которому я добавил распознаватель UILongPressGestureRecogniser, вот так:

 UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc] init];
[lpgr setMinimumPressDuration:1.5];
[lpgr addTarget:self action:@selector(testAction)];
[self.demoButton addGestureRecognizer:lpgr];
  

Однако, когда я нажимаю в течение 1,5 секунд, в консоли отображается следующая ошибка:

2014-07-01 09:50:08.002 ExampleApp[3117:892602] -[ExampleVC testAction]: сообщение отправлено освобожденному экземпляру 0x15cd7bd20 (lldb)*

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

Комментарии:

1. Должен ли селектор быть testAction: вместо testAction ?

2. Нет, в этом нет необходимости

3. Проверьте, действительно ли ваша кнопка, а также представление, в котором включена кнопка, все еще находятся в памяти и еще не были освобождены.

4. Я думаю, вам следует назначить метод Gesture in - (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view , а не где-либо еще. Просто попробуйте.

Ответ №1:

Я думаю, что может возникнуть такая проблема:

 UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc] init];
[lpgr setMinimumPressDuration:1.5];
[lpgr addTarget:self action:@selector(testAction)];
[self.demoButton addGestureRecognizer:lpgr];
  

Вы забыли выпустить lpgr после этих строк.

 [lpgr release];
  

И если вы пропустите эту строку, и iCarussel выпустит кнопку demo из-за оптимизации памяти, ваш распознаватель жестов не будет выпущен и отправит сообщение освобожденной кнопке demoButton.

И используйте длительное нажатие следующим образом:

 [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
  

и обрабатывать:

 - (void)handleLongPress:(UILongPressGestureRecognizer *)gesture{

    if (gesture.state == UIGestureRecognizerStateEnded) {
        //Do Whatever You want on End of Gesture

    }
    else if (gesture.state == UIGestureRecognizerStateBegan){
        //Do Whatever You want on Began of Gesture
    }
}
  

и не забудьте реализовать <UIGestureRecognizerDelegate>

Обновить:

Внутри каждого представления у меня есть UIButton

У вас есть кнопка внутри каждого представления, но в вашем коде я вижу, что у вас есть переменная класса demobutton. Итак, когда вы инициализируете представление, добавьте свою демонстрационную кнопку следующим образом:

     UIView* yourView ...

    UIButton* demoButton = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
    [yourView addSubview:demoButton];

    UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc] init];
    [lpgr setMinimumPressDuration:1.5];
    [lpgr addTarget:self action:@selector(testAction:)];
    [demoButton addGestureRecognizer:lpgr];

    [demoButton release];
    [lpgr release];
  

Комментарии:

1. Применимо ли это также в среде ARC?

2. В ARC вам не нужно освобождать. (и, конечно же, вы не можете, потому что Xcode вам этого не позволяет)

3. Спасибо за это, хотя, к сожалению, сбой все еще происходит даже после внесения этих изменений.

4. Вы кодируете с ARC или без Arc? Включить NSZombie может быть полезно для обнаружения вашей проблемы. После включения обновите свой вопрос новой строкой ошибки. Или опубликуйте весь свой код, и, возможно, я смогу помочь больше.

5. Не могли бы вы, пожалуйста, показать мне свой — (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *) метод просмотра