2010-01-31 7 views
0

실제로 저는 근본 원인을 찾을 수없는 매우 간단한 문제가 있습니다.numberOfRowsInSection은 마지막 부분으로 시작합니다.

문제는 NumberOfSectionsInTableView 메서드를 호출하여 Sections 수 (본인의 경우 24)를 얻은 후에 numberOfRowsInSection 메서드가 호출되지만 마지막 섹션 (23)이 호출된다는 것입니다.

이렇게하면 스크롤 할 때 범위를 벗어나는 인덱스가 생성됩니다.

그래서 어떻게됩니까? 마지막 섹션 (23)의 데이터와 마지막 섹션 (23)의 행 수를받은 후 섹션이 0,1,2,3 등과 같이 앞으로 이동합니다.

예 : 특수 문자에 대한 섹션 헤더가 "#"인 섹션이 있습니다. 필자의 경우 마지막 섹션은 "X"로 시작하는 모든 값의 "X"입니다.

내 앱을 호출 할 때 섹션 제목이 "#"으로 올바르게 설정되었지만 데이터에 "X"값이 모두 표시됩니다. 이 시점에서 저는 31 "X"값을가집니다. 이제 31 행의 마지막으로 스크롤 할 때 인덱스 오류가 발생하여 앱이 다운됩니다.

나는 모든 것이 올바르게 작동 할 것이라고 생각한다. 섹션이 마지막 것에서 시작하지 않을 것이고 이후에 첫번째 것 (23,0,1,2,3,4, etc.)을 계속할 것이라고 생각한다. 섹션 23 또는 23에서 첫 번째 장소의 값이 가장 높은 장소를 찾을 수 없습니다.

은 --- 편집 2가 시작됩니다 :

alphabetArray = [[NSMutableArray alloc] init]; 

먼저 나는이 같은 사전을 채우기 (모든 문자에 포함 특수 문자를.) : 배열 초기화하는

charDict = [[NSMutableDictionary alloc] init]; 

if ([charSpecialArray count] > 0) { 

    [charDict setObject:charSpecialArray forKey:@"Special"]; 
    [alphabetArray addObject:@"Special"]; 
} 

if ([charAArray count] > 0) { 

    [charDict setObject:charAArray forKey:@"A"]; 
    [alphabetArray addObject:@"A"]; 
} 

을 --- 편집 끝 2

그래서 여기에 모든 "#"값 (다른 모든 값으로가는)으로 첫 번째 사전 개체를 채우는 것입니다

여기

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
    return [charDict count]; 
} 

numberOfRowsInSection 간다 :

// Customize the number of rows in the table view. 
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 

NSString *key = [alphabetArray objectAtIndex:section]; 
NSArray *array = [charDict objectForKey:key]; 
return [array count]; 
} 

} 

과 cellForRowAtIndexPath :

는 다음 나는 numberOfSectionsInTableView 메소드를 호출 모든 문자에 대해 다시

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

    static NSString *CellIdentifier = @"Cell"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 


if(cell == nil) 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MyIdentifier"] autorelease]; 

if ([charSpecialArray count] > 0) { 

    Char *charSpecial = (Char *)[[charSpecialArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; 

    cell.textLabel.numberOfLines = 1; 
    cell.detailTextLabel.numberOfLines = 2; 
    [cell.detailTextLabel setFont:[UIFont boldSystemFontOfSize: 12]]; 

    cell.textLabel.text = charSpecial.ta; 
    cell.detailTextLabel.text = charSpecial.descriptionEN; 
} 

if ([charAArray count] > 0) { 

    Char *charA = (Char *)[[charAArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; 

    cell.textLabel.numberOfLines = 1;   
      cell.detailTextLabel.numberOfLines = 2; 
    [cell.detailTextLabel setFont:[UIFont boldSystemFontOfSize: 12]]; 

    cell.textLabel.text = charA.ta; 
    cell.detailTextLabel.text = charA.descriptionEN; 

    } 

을 ...

제안 사항 그것을 고치는 방법? 나는 아직 내 커피를 없었하지만 어떻게이 심지어 것입니다 내가 볼 수없는

#import "SCode.h" 

@implementation Char 

@synthesize ta, report, descriptionDE, descriptionEN; 

-(id)initWithTa:(NSString *)t report:(NSString *)re descriptionDE:(NSString *)dde descriptionEN:(NSString *)den { 
self.ta = t; 
self.report = re; 
self.descriptionDE = dde; 
self.descriptionEN = den; 
return self; 
} 

- (void)dealloc { 

[ta release]; 
[report release]; 
[descriptionDE release]; 
[descriptionEN release]; 
[super dealloc]; 
} 

@end 

답변

2

cellForRowAtIndexPath에 큰 문제가 있습니다. CharsSpecial은 당신이 속한 섹션이 무엇이든 상관없이 (하나의 아이템을 가진 한) 액세스되며, 그 섹션만큼 많은 아이템을 가지고 있지 않을 수도 있습니다. 이것은 충돌을 야기 할 가능성이 큽니다. 코드가 잘 작성된 경우 순서가 잘못된 테이블에서 아무 것도 충돌하지 않아야합니다.

IndexPath에는 두 개의 구성 요소 인 섹션과 행이 있습니다. 2D 배열에서 원하는 데이터를 가져 오려면 [[topArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]을 사용해야합니다. 마찬가지로 numberOfRows는 [[topArray objectAtIndex:indexPath.section] count]을 사용해야하고 numberOfSections는 [topArray count]을 사용해야합니다. 이 방법으로 모든 방법이 일관됩니다. 사전에이를 적용해야 할 필요가 있지만 이는 사소한 것이어야합니다.

일단 테이블을 스크롤하고 데이터 순서에 관한 새로운 질문을 게시하고 listOfItems를 수정하는 모든 코드를 포함하십시오.

편집 :

LISTOFITEMS은 당신이 정말로 할 필요 의미 한 사전을 개최 것으로 보인다. numberOfRows를 더 간단하게 만들 것이기 ​​때문에 사전 대신 배열을 최상위 컨테이너로 사용하는 것이 좋지만이를 사용하려면 사전을 캡슐화하지 않고 바꿔야합니다.

사전을 최상위 컨테이너로 계속 사용하려면 괜찮습니다. listOfItems 배열이 아닌 사전의 항목 수를 계산하려면 numberOfSections를 변경해야합니다. NumberOfRows는 다음과 같이 보일 것입니다 : sectionNameArray 당신이 사전의 키에 사용할 문자열의 배열 (그들은 실제 섹션 이름 일 필요는 없습니다)입니다

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    NSString *key = [sectionNameArray objectAtIndex:section]; 
    NSArray *array = [dictionary objectForKey:key]; 
    return [array count]; 
} 

.

편집 2 :

몇 가지 :

1) alphabetArray 메모리 누수가 이미 ALLOC에 의해 유지되고있어, 당신이 그것을 유지하지 말아야있다.

2) 생략하려는 섹션은 alphabetArray에서 제거해야합니다. 이러한 이유로 빈 배열로 시작하여 if 문 (if ([charAArray count]> 0))에 도달 할 때 문자를 추가하는 것이 좋습니다.

3) cellForRow에서 각 문자 배열의 모든 항목을 각 표 셀에 함께 표시하려고하는 것 같습니다. 이게 너의 의도 야? 마지막 값만 보는 이유는 레이블의 텍스트를 계속 변경하기 때문입니다 (charAArray에 객체가 있으면 charSpecicalArray가 설정 한 값을 덮어 씁니다). 당신이 정말로하고 싶은 것은 위의 코드를 사용하여 하나의 배열을 선택한 다음 indexPath 행을 사용하여 해당 배열에서 하나의 항목을 선택하고 해당 항목을 사용하여 레이블을 설정하는 것입니다. 이 올바른지?

편집 3 :

cellForRowAtIndexPath는 indexPath가 아닌 테이블의 모든 셀 주어진 하나 개의 셀을 반환하기로되어있다.

NSString *key = [alphabetArray objectAtIndex:section]; 
NSArray *array = [charDict objectForKey:key]; 
Char *myChar = (Char *)[array objectAtIndex:indexPath.row]; 

cell.textLabel.numberOfLines = 1; 
cell.detailTextLabel.numberOfLines = 2; 
[cell.detailTextLabel setFont:[UIFont boldSystemFontOfSize: 12]]; 

cell.textLabel.text = myChar.ta; 
cell.detailTextLabel.text = myChar.descriptionEN; 

이는 cellForRowAtIndexPath

+0

안녕 David, 다음과 같이 코드를 변경했습니다. numberOfRowsInSection : NSDictionary * dictionary = [listOfItems objectAtIndex : section]; NSArray * array = [사전 objectForKey : @ "SCodes"]; return [배열 수]; numberOfSectionsInTableView : return [listOfItems count]; cellForRowAtIndexPath : SCode * searchSCodeSpecial = (SCode *) [[searchSCodesSpecial objectAtIndex : indexPath.section] objectAtIndex : indexPath.row]; 불행히도 다음 오류가 발생합니다. 2010-02-13 17 : 15 : 59.756 SCode [425 : 207] *** - [NSCFDictionary objectAtIndex :] : 인식 할 수없는 선택기가 인스턴스 0x76f5bc0으로 전송되었습니다. – Daniel

+0

추측해야한다면 charSpecial은 사전이고 cellForRowAtIndexPath에서는 objectAtIndex를 호출한다고 가정합니다. –

+0

또한 초기화 코드를 확장 할 수 있습니까? 하나의 객체를 사전에 추가하고 해당 사전 만 listOfItems에 추가하는 것으로 보이므로 테이블에는 하나의 객체 만 있습니다. 이 올바른지? –

1

:

#import <UIKit/UIKit.h> 

@interface Char : NSObject { 
NSString *ta; 
NSString *report; 
NSString *descriptionDE; 
NSString *descriptionEN; 
} 

@property (nonatomic, retain) NSString *ta; 
@property (nonatomic, retain) NSString *report; 
@property (nonatomic, retain) NSString *descriptionDE; 
@property (nonatomic, retain) NSString *descriptionEN; 


-(id)initWithTa:(NSString *)t report:(NSString *)re descriptionDE:(NSString *)dde  descriptionEN:(NSString *)den; 

@end 

초기화 코드하는 .m :

초기화 코드 .H 추가 엮다.

이 줄 :

Char *charSpecial = (Char *)[charSpecial objectAtIndex:indexPath.row]; 

은 아마도해야한다 :

Char *charSpecial = (Char *)[charsSpecial objectAtIndex:indexPath.row]; 

참고 "S". NSArray "charsSpecial"을 원할 때 Char 유형 "charSpecial"을가집니다. (이들은 중간에 묻힌 하나의 글자로만 구분되기 때문에 좋은 변수 이름이 아니기 때문에 "charSpecial"을 "charSpecials"또는 "charSpecilsArray"로 변경하는 것이 좋습니다.)

잘 모르겠습니다. 오류는 게시 오타와 비슷해 보입니다.

if ([charSpecial count] > 0) { 

    NSDictionary *charsSpecialDict = [NSDictionary dictionaryWithObject:scodesSpecial forKey:@"Chars"]; 
    [listOfItems addObject:scodesSpecialDict]; 
} 

When I call my App, the section title has been set correctly to "#" but the data shows all the "X" values : 당신은 여기에 같은 문제를 갖고있는 것 같다.

추기경 (색인 된 1 개)으로 숫자 (0) 색인 값을 바꿔야한다고 제안하십시오. 서수 이름을 사용하여 섹션 이름을 올바르게 쿼리하고 있지만 추기로 행을 가져 오는 중입니다. 추기경의 가치는 서수보다 하나 더 많으므로 범위를 벗어난 오류가 발생합니다.

나는 변수 이름을 굴절시켜 코드를 다시 봐야한다고 생각한다.

+0

안녕 TechZen에 if([array count] >0)의 모든 섹션을 교체해야합니다 : 나는 당신이 (당신이하지 않아야) 당신의 편지 배열을 수정할 생각하지 않기 때문에 당신이 원하는 것은이 같은 것입니다 , 첫 번째 오타가 잘못되었습니다 (그냥 내 코드를 약간 익명으로 처리하려고 시도했습니다). 서수 및 추기경에 대해 더 자세히 알려 주실 수 있습니까? 로직이 명확하지만 내 코드에이 코드를 할당 할 수 없습니다 (영어로 불편을 끼쳐 드려 죄송합니다). 특정 코드 예제를 제공 할 수 있습니까? – Daniel

관련 문제