Добавление делегата в пользовательскую UITableViewCell (ошибка неправильного доступа)

Я пытаюсь добавить настраиваемый делегат в свой собственный UITableViewCell.

В этой ячейке у меня есть кнопка, которой нужно запустить метод в ViewController, где находится UITableView.

Я делаю все обычные шаги, чтобы добавить настраиваемого делегата, но по какой-то причине, когда я открываю VC во время выполнения, приложение вылетает и выдает ошибку неправильного доступа.

Когда я комментирую весь код делегата, он работает правильно, поэтому я предполагаю, что что-то не так, как я добавляю свой делегат. Когда я оставляю свое свойство id без комментариев, кажется, что происходит сбой.

Реализую протокол в ВК. Я назначил делегата ячейке в файле cellForRowAtIndexPath:. Все методы делегата на месте. Я использовал подобные конструкции в других классах, но никогда раньше не использовал их в подклассе UITableViewCells.

Прежде чем я опубликую код, я хотел бы знать, сталкивался ли кто-нибудь с этой ошибкой раньше. Если и как он это решил, или возможно ли вообще создать собственный делегат для подкласса UITableViewCell.


РЕДАКТИРОВАТЬ:

Мой customCell.h

#import <UIKit/UIKit.h>

@class MyTableViewCell;

@protocol MyTableCellProtocoll <NSObject>

-(void) didPressButton:(MyTableViewCell *)theCell;

@end

@interface MyTableViewCell : UITableViewCell
{

    UIButton *myButton;

    id<MyTableCellProtocoll> delegationListener;

}

@property (nonatomic,retain) UIButton *myButton;

@property (nonatomic,assign) id<MyTableCellProtocoll> delegationListener;

- (void) buttonAction;

@end

.m

#import "MyTableViewCell.h"

@implementation MyTableViewCell

@synthesize myButton;
@synthesize delegationListener;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code

        self.myButton = [UIButton buttonWithType:UIButtonTypeCustom];
        self.myButton.backgroundColor = [UIColor clearColor];
        self.myButton.frame = CGRectMake(5, 0, 10, 32);
        self.myButton.titleLabel.adjustsFontSizeToFitWidth = YES;
        [self.myButton addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
        [self.contentView addSubview:self.myButton];  
    }
    return self;
}

- (void) buttonAction
{
    NSLog(@"buttonpressed");
    [self.delegationListener didPressButton:self];
}

@end

MyVC реализует делегат надлежащим образом в файле .h.

@interface MyVC : UIViewController <UITableViewDelegate, UITableViewDataSource, MyTableCellProtocoll>

и он также использует один метод делегата из MyTableCellProtocoll в .m

- (void)didPressButton:(MyTableViewCell *)theCell
{
    NSLog(@"didPressButton");
}

Я назначаю делегата в cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{    
    static NSString *CellIdentifier = @"Cell";

    MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[MyTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        cell.delegationListener = self;
    }

    return cell;
}

Это все местоположения, которые я использую для делегата. Я хочу, чтобы он изменил заголовок кнопки и вставил несколько строк после этой ячейки (измененные дубликаты)

Надеюсь, это немного прояснит ситуацию.


EDIT2: метод кнопки не вызывается при запуске, как было указано в разделе комментариев. Отредактированный код с логкодом.


EDIT3: с кнопкой все в порядке. Это свойство делегата, которое где-то перепуталось. С точками останова, журналами и комментариями я убедился в этом.

Код выполняется до последнего элемента в моем списке источников данных, после чего происходит сбой. На 1 шаг ближе к проблеме, я полагаю.


ОКОНЧАТЕЛЬНОЕ РЕДАКТИРОВАНИЕ: Хорошо, похоже, что все делегаты, кнопки и другие компоненты вообще не были проблемой. Это был heightForRowAtIndexPath: меня обманул. Спасибо за вашу поддержку в любом случае!


person Totumus Maximus    schedule 09.11.2011    source источник
comment
Без кода комментировать нельзя. Но да, UITableViewCell может использовать UIViewController в качестве делегата — ваша проблема звучит как стандартное неправильное использование делегатов. И... делегирование может быть не лучшим решением, в зависимости от того.   -  person Paul Lynch    schedule 09.11.2011
comment
Нет причин, по которым было бы невозможно создать протокол делегата и id‹protocol› ivar в подклассе NSObject (каким является UITableViewCell)   -  person jbat100    schedule 09.11.2011
comment
@PaulLynch: я отредактировал вопрос с частью своего кода. В этих местах используются мои действия делегата. Надеюсь, поможет.   -  person Totumus Maximus    schedule 09.11.2011
comment
И... где происходит ПЛОХОЙ ДОСТУП, и я подозреваю, что метод buttonAction может быть каким-то образом вызван из инициализации. Стоит добавить код для проверки (NSLog).   -  person Paul Lynch    schedule 09.11.2011
comment
Кажется, это момент, когда он хочет загрузить табличную ячейку в таблицу. Так как пустая таблица не падает. Добавление к нему элемента или загрузка с элементами в нем приводит к сбою. Старый добрый отладчик не дает мне точное место падения -_-' Также кнопка не вызывается, сделал лог и не появился.   -  person Totumus Maximus    schedule 09.11.2011
comment
Код выполняется до последнего элемента в моем списке источников данных, после чего происходит сбой. На 1 шаг ближе к проблеме, я полагаю.   -  person Totumus Maximus    schedule 09.11.2011
comment
Я думаю, вам нужно поставить точку останова (возможно, в cellForRowAtIndexPath) и точно узнать, где у вас происходит сбой, иначе мы все будем продолжать бросать вам догадки :)   -  person jrturton    schedule 09.11.2011
comment
@jrturton В тот момент, когда он падает после того, как он возвращает 5-й (и последний элемент) некоторого жестко закодированного массива источников данных. После этого он проходит через heighForRowAtIndexPath: и загружает ассемблерный код.   -  person Totumus Maximus    schedule 09.11.2011
comment
Что ж, похоже, это heightForRowAtIndexPath: жестко заданное значение дает мне чистую загрузку. С делегатом работает нормально. Я изменил код там, и теперь он работает. Спасибо за вашу поддержку!   -  person Totumus Maximus    schedule 09.11.2011
comment
Единственная причина, по которой я проголосовал за эту ветку вопросов и ответов, заключается в том, что я ищу настройку протоколов делегатов для UITableViewCell объектов. Здорово!   -  person Randika Vishman    schedule 06.07.2016


Ответы (3)


Я слышал, что синтезированные методы доступа не следует использовать во время init. Попробуйте выполнить весь код установки, используя ivars напрямую:

myButton = [[UIButton alloc] init];         
myButton.backgroundColor = [UIColor clearColor];         
myButton.frame = CGRectMake(5, 0, 10, 32);         myButton.titleLabel.adjustsFontSizeToFitWidth = YES;         
[myButton addTarget:self action:@selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];         
[contentView addSubview:myButton];

Если вы измените создание кнопки на [UIButton buttonWithType:UIButtonTypeCustom];, как правильно предлагает бериллий, вам также потребуется retain ее.

person jrturton    schedule 09.11.2011
comment
Это не кнопка, которая перепуталась здесь, хотя. Когда кнопка полностью закомментирована, она все равно выдает ту же ошибку bad_access. - person Totumus Maximus; 09.11.2011

Этот вопрос был решен. Проблема была не в делегате и не была связана с проблемами кнопок в других ответах. Проблема заключалась в доступе к ячейке в heightForRowAtIndexpath: и была легко решена после ее выяснения.

Jrturton любезно указал мне правильное направление, и за это ему большое спасибо.

person Totumus Maximus    schedule 10.11.2011
comment
Не могли бы вы поделиться решением? - person Varun Naharia; 13.07.2015

Сначала ваш интерфейс назывался MyTableViewCell, реализация - iPadCheckTableViewCell. Я думаю, что оба должны иметь одно и то же имя.

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

self.myButton = [UIButton buttonWithType:UIButtonTypeCustom]; // instead of self.myButton = [[UIButton alloc] init]; - it's a memory leak
person beryllium    schedule 09.11.2011
comment
Ах да, у него такое же имя в моем коде. Это просто опечатка. К сожалению не ошибка. Я сделал правку для этого ^^ - person Totumus Maximus; 09.11.2011