2011-10-25 2 views
3

테이블 뷰의 각 UITableViewCell (2 셀 제외)에 추가되는 UIButton이 있습니다. 버튼의 대상은 UITableViewController입니다. 조치가 잘못된 대상으로 전송되었을 때 앱이 다운 된 것으로 나타났습니다. 나는 이것이 대상이 어떻게 든 할당 해제 되었기 때문에 (비록 UITableViewController가 할당 해제 되었다면 버튼이 보이지 않고 눌러 질 수 없어서 스스로 할당 해제되어야 함에도 불구하고)라고 가정합니다.UIButton 대상 작업 제거

removeTarget을 사용하여 addTarget 메서드의 균형을 잡아야한다고 생각합니다. KVO와 마찬가지로 보유/해제.

그러나 버튼을 생성하고 셀에 추가 할 때 버튼에 대한 참조 만 있기 때문에 어디서해야할지 모르겠습니다. cellForRowAtIndexPath:? 이에있는 UIButton를 서브 클래 싱거나 다음 셀 또는 버튼이 해제 될 때 버튼의 대상 조치를 제거하기 위해 거기에 코드를 넣을 수있는 UITableViewCell를 서브 클래 싱 한 경우

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    static NSString *CellIdentifier = @"Cell"; 

    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease]; 
     UIButton *extraButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
     [extraButton setFrame:CGRectMake(0, 0, 60, 30)]; 
     [extraButton setTitle:@"Meta" forState:UIControlStateNormal]; 
     [extraButton addTarget:self action:@selector(extraButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; 
     cell.accessoryView = extraButton; 
    } 

    if (indexPath.row == kNoExtraButtonRow) { 
     cell.accessoryView.hidden = YES; 
    } else { 
     cell.accessoryView.hidden = NO; 
    } 
    //set textlabels etc... 
    return cell; 
} 

답변

0

. UITableViewCell의 dealloc에서 해당 버튼에 대해 removeTarget을 호출하거나 버튼의 dealloc에서 removeTarget을 자체 호출 할 수 있습니다.

3

이렇게하는 것은 매우 드뭅니다. 무엇보다 다른 방법으로 메모리를 잘못 관리하고있는 것일 수 있습니다. 특히 UIButton의 대상은 일반적으로 해당 버튼을 소유 한 UIViewController이어야합니다. 가장 좋은 디자인에서 버튼은 항상 컨트롤러보다 수명이 짧습니다. UIButton을 다른 곳에 보관 하시겠습니까? nib 파일을 사용하여 버튼을 관리하거나 프로그래밍 방식으로 생성하고 있습니까? 사람들이 프로그래밍 방식으로 UI 요소를 만들 때 우연히 UI 요소의 여러 인스턴스를 만드는 것이 일반적입니다 (nib 파일을 선호하는 몇 가지 이유 중 하나).

모든 ivars (특히이 경우 버튼)에 접근자를 사용해야합니까? ivars에 대한 직접 액세스는 개발자가 중복 된 UI 요소를 만드는 가장 일반적인 방법입니다. 접근자를 항상 사용하십시오 (init 및 dealloc 제외).

+0

세포를 도움이 될 것입니다 생각, 단지 서브 클래스가 아닌있는 UITableViewCell 있습니다. 버튼의 수명이 짧아야합니다. 오류가 발생하면 혼란 스러웠습니다. 나는 펜촉을 사용하지 않고있다. 실수로 UI 요소의 여러 인스턴스를 만드는 것이 무슨 뜻인지 잘 모르겠습니다. 여러 개의 셀이 있으므로 여러 인스턴스를 만들어야합니다. 내 질문에 코드를 추가하겠습니다. –

+0

위의 코드가 올바른 것 같습니다. 실제 충돌 정보를 게시 할 수 있습니다. –

+0

잘'stack '추적은'main' 메소드에서 멈추었으므로 꽤 도움이되지 않습니다. 예외는 : - [_ UIResizableImage extraButtonPressed :] : 인식 할 수없는 셀렉터가 인스턴스 0x29c480에게 보냈습니다. 그리고 이것은 테이블 뷰가 버튼을 포함하고 난 후에 화면을 벗어났습니다 (그래서 버튼을 터치 할 수 없었습니다) –

-1

시도해보십시오.

 if (cell == nil){ 

    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]retain]; 
    UIButton *extraButton = [[UIButton buttonWithType:UIButtonTypeRoundedRect]retain]; 
    [extraButton setFrame:CGRectMake(0, 0, 60, 30)]; 
    [extraButton setTitle:@"Meta" forState:UIControlStateNormal]; 
    [extraButton addTarget:self action:@selector(extraButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; 
    cell.accessoryView = extraButton; 
} 

제거 오토 릴리즈하고 ..... Tableviewcell 할당과 부톤 섬 할당에 유지 추가 할

+0

그러나 이것으로 인해 많은 누수가 발생합니다. –

+0

Ok ... 당신의 extraButtonPressed : 메소드에서 보낸 사람 버튼을 (id) 확인합니다. 한 가지만하고, 버튼에 asign 태그를 지정하고 메소드에서 버튼 id로 태그를 확인하십시오. 나는 그 방법으로 당신이 인식 할 수없는 선택자 오류가있는 곳을 찾았다 고 생각합니다 ..... –

0

당신은 removeTarget 할 필요가 없습니다 당신이 자체로 목표를 설정하고 있는지 확인하십시오. 귀하의 코드는 여기 나를 위해 잘 작동합니다.

0

테이블 뷰 셀이 다시 사용 대기열에 들어 와서 원래대로 돌아 왔다고 가정했지만 정상 확인으로 어쩌면 (cell != nil)이 대기열에서 벗어나고 싶은 경우 removeTarget 그리고 어쨌든 목표물을 재 확립하십시오.

기본적으로 사용자 고유의 인라인 -prepareForReuse(cell != nil) 케이스에 넣고 모든 경우를 설정합니다 (실제 테이블 셀 할당 제외).

+0

미안하지만 저는 꽤 이해하지 못합니다. if 문 밖에서 단추 코드를 이동해야합니까? 그렇게하면 각 셀에 여러 단추가 표시됩니다. –

0
[extraButton addTarget:nil action:@selector(extraButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; 
+0

나는 그것을 제거하는 방법을 알고, 나는이 줄을 어디에 넣어야하는지 알고 싶다. –

2

내가 그것을 잘

[someControl removeTarget:nil 
       action:NULL 
    forControlEvents:UIControlEventAllEvents]; 
관련 문제