2013-06-08 3 views
0

안녕하세요, 테이블 뷰에서 구입 한 IAP 목록을 표시하는 Ray Wenderlich 자습서를 준비하고 있습니다. 테이블보기는 정렬되지 않았으므로 이름별로 정렬됩니다.UITableView의 내용을 정렬하는 중 문제가 발생했습니다.

어느 분류되지 않은 내용, 어떤 내용으로있는 tableview로드, 또는 코드 나 오류 얻을 아래 :

가 [HMContentController unlockedCycleClass] : 인식 할 수없는 선택기 인스턴스에 전송을 0x1e56ee80 2013년 6월 8일 11시 15분 : 47.582 GCC7.1 [6659는 : 907 인한 캐치되지 않는 예외 'NSInvalidArgumentException'이유 응용 프로그램 종료 는 : - : * 여기

인 코드 '[HMContentController unlockedCycleClass] 미정 선택기 인스턴스 0x1e56ee80 전송'하는 I 시도했었다.

HMContenController.h // 모델

#import <Foundation/Foundation.h> 

    UIKIT_EXTERN NSString *const HMContentControllerCurrentCycleClassDidChangeNotification; 
    UIKIT_EXTERN NSString *const HMContentControllerUnlockedCycleClassDidChangeNotification; 


    @class CycleClass; 

    @interface HMContentController : NSObject 

    + (HMContentController *)sharedInstance; 

    - (NSArray *) unlockedCycleClass; 
    - (NSArray *) sortedArray; 

    @property (nonatomic, strong) CycleClass * currentCycleClass; 
(void)unlockCycleClassWithDirURL:(NSURL *)dirURL; 

    @end 

HMContentController.m

#import "HMContentController.h" 
    #import "CycleClass.h" 

    NSString *const HMContentControllerCurrentCycleClassDidChangeNotification = @"HMContentControllerCurrentThemeDidChangeNotification"; 
    NSString *const HMContentControllerUnlockedCycleClassDidChangeNotification = @"HMContentControllerUnlockedThemesDidChangeNotification"; 

    @implementation HMContentController { 

     NSMutableArray * _unlockedCycleClass; 
     NSArray * _sortedArray; //my added code 

    } 

    + (HMContentController *)sharedInstance { 
     static dispatch_once_t once; 
     static HMContentController * sharedInstance; 
     dispatch_once(&once, ^{ 
      sharedInstance = [[self alloc] init]; 
     }); 
     return sharedInstance; 
    } 

    - (id)init { 
     if ((self = [super init])) { 

      _unlockedCycleClass = [NSMutableArray array]; 

      NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];//my added sorting code 
      _sortedArray=[_unlockedCycleClass sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]]; //my added sorting code 



      BOOL hasRunBefore = [[NSUserDefaults standardUserDefaults] boolForKey:@"hasRunBefore"]; 
      if (!hasRunBefore) { 
       [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"hasRunBefore"]; 
       [[NSUserDefaults standardUserDefaults] synchronize]; 
       [self setHints:20]; 
      } 
     } 
     return self; 
    } 


    - (void)setCurrentCycleClass:(CycleClass *)currentCycleClass { 
     _currentCycleClass = currentCycleClass; 
     [[NSNotificationCenter defaultCenter] postNotificationName:HMContentControllerCurrentCycleClassDidChangeNotification object:nil]; 
    } 



- (NSArray *)unlockedCycleClass { 
    return _unlockedCycleClass; 
} 


    - (void)unlockCycleClassWithDirURL:(NSURL *)dirURL { 

     CycleClass * cycleClass = [[CycleClass alloc] initWithDirURL:dirURL]; 

     // Make sure we don't already have class 
     BOOL found = FALSE; 
     for (int i = 0; i < _sortedArray.count; ++i) { 
      CycleClass * curCycleClass = _unlockedCycleClass[i]; 
      if ([cycleClass.name isEqualToString:curCycleClass.name]) { 
       NSLog(@"Cycle Class already unlocked, replacing..."); 
       if (self.currentCycleClass == curCycleClass) { 
        self.currentCycleClass = cycleClass; 
       } 
       _unlockedCycleClass[i] = cycleClass; 
       found = TRUE; 
       break; 
      } 
     } 
     if (!found) { 
      // Unlock new theme 
      [_unlockedCycleClass addObject:cycleClass]; 
     } 
     if (!self.currentTheme) { 
      self.currentCycleClass = cycleClass; 
     } 

     // Notify observers 
     [[NSNotificationCenter defaultCenter] postNotificationName:HMContentControllerUnlockedCycleClassDidChangeNotification object:self]; 
    } 


    - (void)unlockContentWithDirURL:(NSURL *)dirURL { 

     if ([CycleClass classAtURL:dirURL]) { 
      [self unlockCycleClassWithDirURL:dirURL]; 
     } 

     else if ([HMTheme themeAtURL:dirURL]) { 
      [self unlockThemeWithDirURL:dirURL]; 
     } else if ([HMWords wordsAtURL:dirURL]) { 
      [self unlockWordsWithDirURL:dirURL]; 
     } else { 
      NSLog(@"Unexpected content!"); 
     } 

    } 

    @end 

MyCycleClass //의 tableview

#import "MyCycleClassesViewController.h" 
#import "HMContentController.h" 
#import "CycleClass.h" 

@interface MyCycleClassesViewController() <UIActionSheetDelegate> 

@property (weak, nonatomic) IBOutlet UILabel *classLabel; 

@end 

@implementation MyCycleClassesViewController { 

    NSIndexPath * _selectedIndexPath; 

} 



- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 
    [[self tableView] reloadData]; //refresh table 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(unlockedCycleClassChanged:) name:HMContentControllerUnlockedCycleClassDidChangeNotification object:nil]; 


} 

- (void)viewWillDisappear:(BOOL)animated { 
    [super viewWillDisappear:animated]; 

    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 

- (void)unlockedCycleClassChanged:(NSNotification *)notification { 
    [self.tableView reloadData]; 
} 


#pragma mark - Table view data source 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    // Return the number of sections. 
    return 1; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    return [HMContentController sharedInstance].unlockedCycleClass.count; 
} 

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

    CycleClass * class = [HMContentController sharedInstance].sortedArray[indexPath.row]; //originally sortedArray was .unlockedCycleClass which loaded unordered classes 
    if ([HMContentController sharedInstance].currentCycleClass == class) { 
     cell.accessoryType = UITableViewCellAccessoryCheckmark; 
     _selectedIndexPath = indexPath; 
    } else { 
     cell.accessoryType = UITableViewCellAccessoryNone; 
    } 
    cell.textLabel.text = class.name; 

    return cell; 
} 

#pragma mark - Table view delegate 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    [tableView deselectRowAtIndexPath:indexPath animated:YES]; 

    NSMutableArray * indexPathsToReload = [NSMutableArray array]; 
    if (_selectedIndexPath) { 
     [indexPathsToReload addObject:_selectedIndexPath]; 
    } 
    if (![indexPath isEqual:_selectedIndexPath]) { 
     [indexPathsToReload addObject:indexPath]; 
    } 

    CycleClass * class = [HMContentController sharedInstance].sortedArray[indexPath.row]; 
    [[HMContentController sharedInstance] setCurrentCycleClass:class]; 



    [self.tableView reloadRowsAtIndexPaths:indexPathsToReload withRowAnimation:UITableViewRowAnimationNone]; 

} 

@end

CycleClass.h/m (그냥 그게 지옥이야. pful의 IAP 정보)

#import <Foundation/Foundation.h> 

@interface CycleClass : NSObject 

@property (nonatomic, readonly, strong) NSURL * dirURL; 
@property (nonatomic, readonly, strong) NSString * name; 
@property (nonatomic, readonly, strong) NSURL * noMusicURL; 
@property (nonatomic, readonly, strong) NSURL * withMusicURL; 
@property (nonatomic, readonly, strong) NSURL * imageURL; 

+ (BOOL)classAtURL:(NSURL *)url; 
- (id)initWithDirURL:(NSURL *)url; 



@end  

import "CycleClass.h" 

@implementation CycleClass 

+ (BOOL)classAtURL:(NSURL *)url { 
    NSURL * plistURL = [url URLByAppendingPathComponent:@"cycleClass.plist"]; 
    return [[NSFileManager defaultManager] fileExistsAtPath:plistURL.path]; 
} 


- (id)initWithDirURL:(NSURL *)url { 
    if ((self = [super init])) { 

     _dirURL = url; 

     NSURL * plistURL = [url URLByAppendingPathComponent:@"cycleClass.plist"]; 
     NSDictionary * dict = [NSDictionary dictionaryWithContentsOfURL:plistURL]; 
     if (dict == nil) return nil; 

     _name = dict[@"name"]; 

     NSString * noMusicString = dict[@"noMusic"]; 
     if (noMusicString) { 
      _noMusicURL = [url URLByAppendingPathComponent:noMusicString]; 
     } 
     NSString * withMusicString = dict[@"withMusic"]; 
     if (withMusicString) { 
      _withMusicURL = [url URLByAppendingPathComponent:withMusicString]; 
     } 


     NSString * imageString = dict[@"image"]; 
     if (imageString) { 
      _imageURL = [url URLByAppendingPathComponent:imageString]; 
     } 
    } 
    return self; 
} 


@end 

그리고 IAP의 PLIST

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 
<plist version="1.0"> 
<dict> 
    <key>name</key> 
    <string>2. Simon Beginner Hills</string> 
    <key>noMusic</key> 
    <string>simon2NoMusic.mp3</string> 
    <key>withMusic</key> 
    <string>simon2Music.mp3</string> 
    <key>image</key> 
    <string>simongraph2.png</string> 
</dict> 
</plist> 

나는 완전히이 난처한 상황에 빠진거야하지만, 간단한 명백한 수정이 있어야처럼 보인다는 ... 도와주세요!

+0

방금 ​​프로젝트를 빌드 할 때 경고가 있습니까? 나는 당신이 가지고 있어야한다고 생각한다) – makaron

+0

ARC를 사용하고 있습니까? – Dabrut

+1

배열을 비운 후에 바로 정렬합니다. 배열을 채운 후 정렬을 수행하십시오. – rdelmar

답변

0

rdelmar가 말했듯이 배열을 채운 후에는 정렬해야합니다.

unlockedCycleClass (클래스가 아닌 Array 임)가 업데이트 될 때마다 sortedArray가 업데이트되는지 확인하려고합니다. 당신이

[_unlockedCycleClass addObject:cycleClass]; 

이 일을 할 수있는 가장 효율적인 방법은 아니다 이렇게 후 unlockCycleClassWithDirURL 기능 내부

NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];//my added sorting code 
_sortedArray=[_unlockedCycleClass sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]]; //my added sorting code 

,하지만 난 그것을 생각 : 그래서 HMContentController.m에 예, 당신은 당신의 라인을 반복 수 작동해야합니다.

+0

고마워, 추가 라인을 추가했지만 여전히 오류가 발생합니다. "sortedArray"올바르게 UITableView 사용하고 있습니까? 또한, 사이드 노트, "cycleClass"는 프로그래밍 클래스에 프로그래밍 클래스 객체를 설명하므로 내 설명자는 다소 혼란 스럽습니다 ... 아마 cycleClassArray가 더 좋을 것입니다. – BenHedges

관련 문제