【问题标题】:Problems trying to override methods in Objective-C (iPhone)尝试覆盖 Objective-C (iPhone) 中的方法时出现问题
【发布时间】:2009-12-17 18:39:51
【问题描述】:

这是我的问题,我有一个继承 UITableViewController 类的类 X 和一个继承 X 类的类 Y,当我尝试覆盖 Y 类中的方法时,会调用 X 类中的方法......我可以'找不到参考资料以了解正在发生的事情...有人可以帮助我吗?

提前致谢!

代码!

mluListBuilder.h

#import <UIKit/UIKit.h>

@interface mluListBuilder : UITableViewController {
    NSString                *sListTitle;
    NSString                *sEntityName;
    NSArray                 *aEntityProperties;
    NSMutableArray          *maListRecords;
    NSManagedObjectContext  *mocList;
    NSFetchRequest          *frListRecords;
    NSEntityDescription     *edListRecords;
    NSArray                 *aOrderByProperties;
    NSArray                 *aToolBarItems;
    NSArray                 *aToolBarItemsActions;
}

@property (nonatomic, retain) NSString                  *sListTitle;
@property (nonatomic, retain) NSString                  *sEntityName;
@property (nonatomic, retain) NSArray                   *aEntityProperties;
@property (nonatomic, retain) NSMutableArray            *maListRecords;
@property (nonatomic, retain) NSManagedObjectContext    *mocList;
@property (nonatomic, retain) NSFetchRequest            *frListRecords;
@property (nonatomic, retain) NSEntityDescription       *edListRecords;
@property (nonatomic, retain) NSArray                   *aOrderByProperties;
@property (nonatomic, retain) NSArray                   *aToolBarItems;
@property (nonatomic, retain) NSArray                   *aToolBarItemsActions;


- (id) initWithStyle:           (UITableViewStyle)  style
    listTitle:                  (NSString *)        psListTitle
    entityName:                 (NSString *)        psEntityName 
    entityProperties:           (NSArray *)         paEntityProperties
    orderListByProperties:      (NSArray *)         paOrderByProperties
    toolBarItems:               (NSArray *)         paToolBarItems
    toolBarItemsActions:        (NSArray *)         paToolBarItemsActions;

- (void)newRecord;
- (void)deleteRecord;

@end

mluListBuilder.m

#import "mluListBuilder.h"

@implementation mluListBuilder

@synthesize sListTitle,
            sEntityName,
            aEntityProperties,
            maListRecords,
            mocList,
            frListRecords,
            edListRecords,
            aOrderByProperties,
            aToolBarItems,
            aToolBarItemsActions;


- (id) initWithStyle:           (UITableViewStyle)  style
    listTitle:                  (NSString *)        psListTitle
    entityName:                 (NSString *)        psEntityName 
    entityProperties:           (NSArray *)         paEntityProperties
    orderListByProperties:      (NSArray *)         paOrderByProperties
    toolBarItems:               (NSArray *)         paToolBarItems
    toolBarItemsActions:        (NSArray *)         paToolBarItemsActions
{

    sListTitle              = psListTitle;
    sEntityName             = psEntityName;
    aEntityProperties       = paEntityProperties;
    aOrderByProperties      = paOrderByProperties;
    aToolBarItems           = paToolBarItems;
    aToolBarItemsActions    = paToolBarItemsActions;

    if (self = [super initWithStyle:style]) {
    }
    return self;
}

- (void)viewDidLoad {
    self.title = NSLocalizedString(sListTitle, nil);

    if ([aToolBarItems count] > 0) {
        NSMutableArray *maToolBarItems = [[NSMutableArray alloc] init];
        self.navigationController.toolbarHidden = NO;
        for (int i = 0; i < [aToolBarItems count]; i++) {
            UIBarButtonItem * bbiToolBarItem = [[UIBarButtonItem alloc] 
                                                initWithTitle:NSLocalizedString([aToolBarItems objectAtIndex:i], nil)
                                                style:UIBarButtonItemStyleBordered
                                                target:self 
                                                action:NSSelectorFromString([aToolBarItemsActions objectAtIndex:i])
                                                ];


            [maToolBarItems addObject:bbiToolBarItem];
        }
        self.toolbarItems = maToolBarItems;
    } else {
        self.navigationController.toolbarHidden = YES;
    }

    if (mocList != nil) {
        frListRecords = [[NSFetchRequest alloc] init];

        NSSortDescriptor *sdListRecords = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];

        [frListRecords setSortDescriptors:[[NSArray alloc] initWithObjects:sdListRecords, nil]];

        edListRecords = [NSEntityDescription entityForName:sEntityName inManagedObjectContext:mocList];

        [frListRecords setEntity:edListRecords];

        NSError *errFetchRequest;
        maListRecords = [[mocList executeFetchRequest:frListRecords error:&errFetchRequest] mutableCopy];
    }
    [super viewDidLoad];
}

- (void)viewWillAppear:(BOOL)animated {
    NSError *errFetchRequest;
    maListRecords = [[mocList executeFetchRequest:frListRecords error:&errFetchRequest] mutableCopy];
    [self.tableView reloadData];

    if (self.navigationController.toolbarHidden == YES) {
        if ([aToolBarItems count] > 0) {
            self.navigationController.toolbarHidden = NO;
        }
    }
}

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


#pragma mark Table view methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [maListRecords count];
}


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

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

    for (UIView *vwExisting in cell.contentView.subviews) {
        [vwExisting removeFromSuperview];
    }

    NSEntityDescription *edCurrentRecord = [maListRecords objectAtIndex:indexPath.row];

    UILabel *lblCell = [[UILabel alloc] initWithFrame:CGRectMake(5.0, 5.0, 280, 20.0)];
    [lblCell setText:edCurrentRecord.name];

    [cell.contentView addSubview:lblCell];

    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];

    return cell;
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // Navigation logic may go here. Create and push another view controller.
    // AnotherViewController *anotherViewController = [[AnotherViewController alloc] initWithNibName:@"AnotherView" bundle:nil];
    // [self.navigationController pushViewController:anotherViewController];
    // [anotherViewController release];
}

- (void)dealloc {
    [super dealloc];
}

- (void)newRecord {
    NSLog(@"%@", [self class]);
}

- (void)deleteRecord {

}

@end

mluLawyerCaseSituationsList.h

#import <Foundation/Foundation.h>
#import "mluListBuilder.h";

@interface mluLawyerCaseSituationsList : mluListBuilder {

}

- (void)newRecord;

@end

mluLawyerCaseSituationsList.m

#import "mluLawyerCaseSituationsList.h"

@implementation mluLawyerCaseSituationsList

- (void)newRecord {
    NSLog(@"%@", [self class]);
}

@end

调用 mluLawyerCaseSituationsList

mluLawyerCaseSituationsList *vcCaseSituations = [[mluListBuilder alloc]
                                                     initWithStyle:UITableViewStylePlain
                                                     listTitle:@"titCaseSituations" 
                                                     entityName:@"case_situations" 
                                                     entityProperties:[[NSArray alloc] initWithObjects:@"name", nil] 
                                                     orderListByProperties:[[NSArray alloc] initWithObjects:@"name", nil] 
                                                     toolBarItems:[[NSArray alloc] initWithObjects:@"btNew", nil]
                                                     toolBarItemsActions:[[NSArray alloc] initWithObjects:@"newRecord", nil]
                                                     ];

输出... :(

2009-12-17 17:30:02.726 mluLawyer[2862:20b] mluListBuilder

希望对你有帮助...

【问题讨论】:

  • 没有代码没有办法帮你。通常,覆盖在 Objective-C 中效果很好。你的代码一定有问题。
  • 根据个人经验,我强烈建议不要扩展 UITableViewController(或任何类似提供的类)来创建可重用的扩展点。你不知道 Apple 最初的实现中发生了什么,它只会在以后导致一袋子伤害。相反,将常见行为归为一类。

标签: iphone objective-c inheritance overriding


【解决方案1】:

我只是简单地浏览了您的代码,但很明显(从代码和输出中)您分配了一个类 X (mluListBuilder) 的实例。

当然,你不能指望有一个 Y 类 (mluLawyerCaseSituationsList) 的方法,当 Y 从 X 派生并且对象属于 X 类时执行。

【讨论】:

    【解决方案2】:

    所以,你有:

    @interface X : UITableViewController
    - (void) method;
    @end
    
    @interface Y : X
    - (void) method;
    @end
    

    您正在调用-method,但它是在 X 而不是 Y 上调用的?唯一可能发生的方法是,如果您有一个 X 实例而不是 Y 实例(或者如果有人在运行时玩非常愚蠢的虫子——不太可能)。

    在方法实现中添加NSLog(@"%@", [self class]);,看看实例的类到底是什么!

    【讨论】:

      【解决方案3】:

      您在问题中没有向我们提供太多信息,但以下是它应该的工作方式:

      Class_X.h:

      @interface Class_X : UITableViewController
      {
      }
      - (void)someMethod;
      @end
      

      Class_X.m:

      #import "Class_X.h"
      
      @implementation Class_X
      - (void)someMethod
      {
          NSLog(@"method in Class_X was called");
      }
      @end
      

      Class_Y.h:

      #import "Class_X.h"
      
      @interface Class_Y : Class_X
      {
      }
      - (void)someMethod;
      @end
      

      Class_Y.m:

      #import "Class_Y.h"
      
      @implementation Class_Y
      - (void)someMethod
      {
          NSLog(@"method in Class_Y was called");
      }
      @end
      

      其他地方:

      #import "Class_Y.h"
      
      ...
      
      Class_X * x_instance = [[Class_X alloc] init];
      Class_Y * y_instance = [[Class_Y alloc] init];
      
      [x_instance someMethod];
      [y_instance someMethod];
      
      [Class_Y release];
      [Class_X release];
      

      输出:

      method in Class_X was called
      method in Class_Y was called
      

      【讨论】:

        猜你喜欢
        • 2012-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多