Reputation: 22962
From the outside I would like my class to appear like this
@interface MYCardGroupView : UIView
@property (nonatomic, strong) NSArray *cardObjects;
@end
But within the class itself I want it to actually be a UITableView
@interface MYCardGroupView : UITableView <UITableViewDataSource, UITableViewDelegate>
@property (nonatomic, strong) NSArray *cardObjects;
@end
Arguments for:
Upvotes: 3
Views: 565
Reputation: 22962
This works from a functional perspective, but has following drawbacks
+[MYCardGroupView alloc]
: Incompatible pointer types returning 'MYPrivateCardGroupView *' from a function with result type 'MYCardGroupView *'
@interface MYCardGroupView : UIView
@property (nonatomic, strong) NSArray *cardObjects;
@end
#import "MYCardGroupView.h"
@interface MYPrivateCardGroupView : UITableView <UITableViewDataSource, UITableViewDelegate>
@property (nonatomic, strong) NSArray *cardObjects;
@end
@implementation MYCardGroupView
+ (id)alloc
{
return [MYPrivateCardGroupView alloc];
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self)
{
NSLog(@"My class is %@", [self class]);
}
return self;
}
@end
@implementation MYPrivateCardGroupView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self)
{
NSLog(@"My class is %@", [self class]);
}
return self;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 10;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
cell.textLabel.text = @"hello";
return cell;
}
@end
My class is MYPrivateCardGroupView
Upvotes: 0
Reputation: 53000
What you are after is effectively a class cluster, with a cluster size of 1 - unusual maybe but quite legitimate.
A number of classes in the standard frameworks; e.g. NSString
; are implemented as clusters where the public class is "abstract" (not in the traditional OO sense) and one or more private classes provide the actual implementation(s). On creating an instance of the public class its init
(or alloc
) substitutes and instance of one of the private classes.
This is a well defined model in Cocoa, see Apple's Cocoa Core Competencies: Class Cluster
Upvotes: 1
Reputation: 47729
One could, in theory, employ two separate .h files, one "real" one, only named "MyClass_real.h" and one fake one, named "MyClass.h". Include the real one in your .m but use the fake one as the advertised interface. The fake one could say your base class is "Potato" and it wouldn't make any difference.
(One would have to be a bit concerned about ARC, I suppose. It might get upset.)
Upvotes: 4
Reputation: 100622
You can declare the protocols outside of the header (via a class extension — an unnamed category) but not technically the inheritance. That's because usually you want the inheritance to be known.
Immediately obvious workarounds include:
UIView
, have its init
or alloc
substitute an instance of another class that otherwise follows the same published interface but is a sub of UITableViewController
; andclass_setSuperclass
(deprecated since day one but still available) to change your superclass at init
.Upvotes: 2
Reputation: 8200
You can hide the protocols it implements (like UITableViewDataSource
and UITableViewDelegate
) by adding them to a class extension in your .m file. But you can't hide that it's a UITableView subclass.
However, it shouldn't hurt performance to have an extra UIView, at least not in any noticeable way. There are extra views that you don't notice all over the place in the built-in UIKit elements, and the impact is likely very minimal. If you're that worried about performance, leave it as a UITableView subclass. But if you're not so worried and you care more about concealing as much as possible, make it a UIView subclass and have it encapsulate a UITableView instead.
Upvotes: 2