Pass parameter when initializing table - iphone

Okay, I'm totally stumped here.
This works in CouponListViewController.m:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.couponList = [CouponDatabase database].couponList;
self.title = #"Coupon List";
}
And this works in CouponDetailViewController.m:
- (void)viewWillAppear:(BOOL)animated {
CouponDetails *details = [[CouponDatabase database] couponDetails:_uniqueId];
if (details != nil) {
[_merchantNameLabel setText:details.merchantName];
[_longDealLine1Label setText:details.longDealLine1];
//....blah...blah//
}
}
But when I change the CouponDatabase.h from this (which works with the above):
#class CouponDetails;
#interface CouponDatabase : NSObject {
sqlite3 *_database;
}
+ (CouponDatabase *)database;
- (NSArray *)couponList;
- (CouponDetails *)couponDetails:(int) uniqueId;
...to this (which works if I manually set the value of 'selectedCategory' inside the method):
#class CouponList;
#class CouponDetails;
#interface CouponDatabase : NSObject {
sqlite3 *_database;
}
+ (CouponDatabase *)database;
- (CouponList *)couponList:(int) selectedCategory;
- (CouponDetails *)couponDetails:(int) uniqueId;
and then change CouponListViewController.m to this:
1 - (void)viewWillAppear:(BOOL)animated {
2 [super viewWillAppear:animated];
3 self.couponList = [[CouponDatabase database] couponList:_selectedCategory];
4 self.title = #"Coupon List";
5 }
I get this error on line 3 above:
warning: incompatible Objective-C types 'struct CouponList *',
expected 'struct NSArray *' when passing argument 1 of 'setCouponList:'
from distinct Objective-C type
Question: What is the proper formatting of the 'self.couponlist' line so that I can pass an integer to the CouponDatabase for use in the couponList method?
EDIT: I'm aware that couponDetails is now a class instead of an array - I just don't know know how to format the line to initialize the table data.
I hope this makes sense - any help on this would be very greatly appreciated.
Thanks in advance!
Adding CouponListViewController.h:
#import <UIKit/UIKit.h>
#class CouponDetailsViewController;
#interface CouponListViewController : UITableViewController {
NSArray *_couponList;
CouponDetailsViewController *_couponDetails;
int _selectedCategory;
}
#property (nonatomic, retain) NSArray *couponList;
#property (nonatomic, retain) CouponDetailsViewController *couponDetails;
#property(nonatomic, assign) int selectedCategory;
#end

Try changing your CouponListViewController.h to this:
#import <UIKit/UIKit.h>
#class CouponDetailsViewController;
#interface CouponListViewController : UITableViewController {
CouponList *_couponList;
CouponDetailsViewController *_couponDetails;
int _selectedCategory;
}
#property (nonatomic, retain) CouponList *couponList;
#property (nonatomic, retain) CouponDetailsViewController *couponDetails;
#property(nonatomic, assign) int selectedCategory;
#end
Oops I put my response in my own original post and should have put it here:
Edit: Okay, I made changes to CouponListViewController.h as recommended by Robert, plus added #class CouponList; as follows:
#import <UIKit/UIKit.h>
#class CouponList;
#class CouponDetailsViewController;
#interface CouponListViewController : UITableViewController {
CouponList *_couponList;
CouponDetailsViewController *_couponDetails;
int _selectedCategory;
}
#property (nonatomic, retain) CouponList *couponList;
#property (nonatomic, retain) CouponDetailsViewController *couponDetails;
#property(nonatomic, assign) int selectedCategory;
#end
I'm still getting errors in CouponListViewController.m:
#import "CouponListViewController.h"
#import "CouponDatabase.h"
#import "CouponList.h"
#import "CouponDetailsViewController.h"
#implementation CouponListViewController
#synthesize couponList = _couponList;
#synthesize couponDetails = _couponDetails;
#synthesize selectedCategory = _selectedCategory;
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.couponList = [CouponDatabase database].couponList; // <--- ERROR 1
self.title = #"Coupon List";
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_couponList count]; // <--- WARNINGS 1 AND 2
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (self.couponDetails == nil) {
self.couponDetails = [[[CouponDetailsViewController alloc] initWithNibName:#"CouponDetailsViewController" bundle:nil] autorelease];
}
CouponList *info = [_couponList objectAtIndex:indexPath.row]; // <--- WARNING 3
NSLog(#"%#", info.uniqueId);
_couponDetails.uniqueId = info.uniqueId;
[self.navigationController pushViewController:_couponDetails animated:YES];
}
ERROR 1: request for member 'couponList' in something not a structure or union
WARNING 1: 'CouponList' may not respond to '-count'
WARNING 2: return makes integer from pointer without a cast
WARNING 3: 'CouponList' may not respond to '-objectAtIndex:'

In you original code for CouponDatabase, you are changing the definition:
- (NSArray *)couponList;
for this one:
- (CouponList *)couponList:(int) selectedCategory;
Nevertheless, you use that return value as datasource for a list view controller, so . Here you have a mismatch you should fix. How to fix it depends on the semantics of your application. What are your trying to do with - (CouponList *)couponList:(int) selectedCategory;? What does really return this selector? What is the interface CouponList? Possibly you should change the line:
self.couponList = [[CouponDatabase database] couponList:_selectedCategory];
so that it returns an NSArray build from a CouponList. But I am not sure of the semantics of your objects, so this might not be the case.

Related

Delegate method not working ios

I used delegate mehod for pass data between view controllers. This is not working.
#protocol PassCountry <NSObject>
#required
- (void) setPickedCountry:(NSString *)pickedCountry;
#end
#interface SelectCountryViewController : UIViewController<UIPickerViewDelegate, UIPickerViewDataSource> {
id <PassCountry> delegate;
}
#property (copy) NSString *pickedCountry;
#property (retain) id delegate;
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent (NSInteger)component {
pickedCountry = [self.countries objectAtIndex:row];
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return self.countries.count;
}
- (void)viewWillDisappear:(BOOL)animated {
[[self delegate] setPickedCountry:pickedCountry];
}
#import <UIKit/UIKit.h>
#protocol PassCountry <NSObject>
#required
- (void) setPickedCountry:(NSString *)pickedCountry;
#end
#interface secondViewViewController : UIViewController<UIPickerViewDelegate, UIPickerViewDataSource>
{
id <PassCountry> delegate;
IBOutlet UIButton *aButton;
}
#property (copy) NSString *pickedCountry;
#property (assign) id<PassCountry> delegate; // for delegate use assign don't retain
// in another class you are creating instance of this class
secondViewViewController *secController = [[secondViewViewController alloc]init];
secController.delegate = self;//check this added or not
[self presentViewController:secController animated:YES completion:nil];
//and implementation of deleagte method
- (void) setPickedCountry:(NSString *)pickedCountry
{
// do some stuff
}
Firstly, delegate instance can not be retained.
Secondly, delegate should be synthesized using "#synthesize delegate" before invoke the method [self delegate].
Try this::
.h File
#protocol delegateTextSize <NSObject>
#optional
-(void)selectedTextSize:(double)textSize;
#end
#interface CustomFontSizeCell : UITableViewCell
#property (nonatomic,retain) id delegateTextSize;
-(IBAction)changeSize:(id)sender;
#end
.m File
-(IBAction)changeSize:(id)sender
{
[delegateTextSize selectedTextSize:app.selectedFontSize];
}
Where to use,
.h File
Controller <delegateTextSize>
.m File
-(void)selectedTextSize:(double)textSize
{
}
Hopefully, this will work
Thanks.

numberOfRowsInSection not being called for UITableView

I am having some issues where my UITableView is not reloading, I have redone the linking of the outlet to make sure that was not the issue. I have also tried using [self table] reloadData] but that does not seem to work either. I have debugged the issues, but it simply skips reloadData and the app keeps running like the code is not even there.
Top part of my .m file, nothing is done in ViewDidLoad
#import "SettingsCourses.h"
#implementation SettingsCourses
#synthesize settingsCourses;
#synthesize Delegate;
#synthesize BackButton;
#synthesize DeleteButton;
#synthesize table;
#synthesize courses;
#synthesize dataHandler;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
dataHandler = [[DataHandler alloc] init];
dataHandler.coursesDelegate = self;
courses = [dataHandler fetchCourses];
NSLog(#"Debug Count: %i", [courses count]);
}
[table reloadData];
return self;
}
- (void) viewWillAppear:(BOOL)animated {
[table reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (courses) {
NSLog(#"Count: %i", [courses count]);
return [courses count];
}
else {
NSLog(#"Count: 0");
return 0;
}
}
My .h file
#import <UIKit/UIKit.h>
#import "dataHandler.h"
#interface SettingsCourses : UIViewController
#property (strong, nonatomic) DataHandler *dataHandler;
#property (strong, nonatomic) NSMutableArray *courses;
#property (strong, nonatomic) IBOutlet UIView *settingsCourses;
#property (nonatomic, strong) id Delegate;
#property (weak, nonatomic) IBOutlet UIButton *BackButton;
#property (weak, nonatomic) IBOutlet UIButton *DeleteButton;
#property (weak, nonatomic) IBOutlet UITableView *table;
- (IBAction)Delete:(id)sender;
- (IBAction)Back:(id)sender;
Thanks for any help!
add this lines:
- (void)viewDidLoad {
[super viewDidLoad];
self.table.dataSource = self;
self.table.delegate = self;
}
but much easier would be to set the datasource in interface-build aka the XIB file.
Try this
#interface SettingsCourses : UIViewController <UITableViewDelegate,UITableViewDataSource>
You do not appear to be setting the table delegate or datasource. To do this just add the following code when in your unit method
table.dataSource = self or wherever your data source is;
table.delegate = self:
YOu might want to try to disconnect and reconnect datasource and delegate in the interface builder. IB sometimes "forgets" connections.
I had setup a UITableViewController in IB, but its class name didn't match the UITableViewController file I had. Rookie!
The error for me was that I was returning 0 in
func numberOfSections(in tableView: UITableView) -> Int

Sharing Data between XIB's

I'm following the James Brannan tutorial's, and im trying to share data between some xbis. No luck.
I have 2 xib's. The first, simple button and textfield. The second, just a label, to show the result of the first xib textfield.
So, i dont know what im doing wrong. Im using NSObject like in tutorial.
SharedData.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#interface SharedData : NSObject {
NSString *MeuNome;
}
#property (nonatomic, retain) NSString *MeuNome;
#end
SharedData.m
#import "SharedData.h"
#implementation SharedData
#synthesize MeuNome;
- (void) dealloc {
self.MeuNome = nil;
[super dealloc];
}
#end
FirstStepViewController.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "SharedData.h"
#interface FirstStepViewController : UIViewController {
IBOutlet SharedData *sharedData;
IBOutlet UITextField *campoNome;
}
#property (nonatomic, retain) UITextField * campoNome;
#property (nonatomic, retain) SharedData *sharedData;
- (IBAction) takeNextStep: (id) sender;
#end
FirstStepViewController.m
#import "FirstStepViewController.h"
#import "SecondStepViewController.h"
#import "LuconeAppDelegate.h"
#implementation FirstStepViewController
#synthesize campoNome, sharedData;
- (IBAction) takeNextStep : (id) sender{
// declaracao de shared data
[sender resignFirstResponder];
self.sharedData.MeuNome = self.campoNome.text;
// faz animacao para proximo slide
SecondStepViewController *varSecondViewController = [[SecondStepViewController
alloc] initWithNibName:#"SecondStepViewController" bundle:nil ];
[self.navigationController pushViewController:varSecondViewController
animated: YES];
[self navigationController].navigationBarHidden = NO;
}
- (void)viewDidLoad {
[self navigationController].navigationBarHidden = YES;
[super viewDidLoad];
}
- (void)dealloc {
self.sharedData = nil;
//self.campoNome = nil;
[super dealloc];
}
#end
SecondStepViewController.h
#import <UIKit/UIKit.h>
#import "SharedData.h"
#interface SecondStepViewController : UIViewController {
IBOutlet SharedData *sharedData;
IBOutlet UILabel *nome;
}
#property (nonatomic, retain) SharedData *sharedData;
#property (nonatomic, retain) UILabel *nome;
#end
SecondStepViewController.m
#import "SecondStepViewController.h"
#import "SharedData.h"
#implementation SecondStepViewController
#synthesize nome, sharedData;
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = #"step two";
self.nome.text = self.sharedData.MeuNome;
}
- (void)dealloc {
self.sharedData = nil;
[super dealloc];
}
#end
What's wrong?
Thanks!
There are three small problems with your code.
IBOutlet is only for controls that you put on your view using interface builder e.g. UIButtons, UILabels. So it is unnecessary for instances of SharedData to be IBOutlets. Furthermore if you create your interface programmatically then using IBOutlet is again unnecessary.
You Declare that sharedData is an instance of SharedData class but you do not instantiate it. in your FirstStepViewController.m before you set any of sharedData's properties you should add the following code:
sharedData = [[sharedData alloc] init];
after that you can do:
self.sharedData.MeuNome = self.campoNome.text;
if you omit the "self." the code should work just as fine.
Finally before pushing the second view controller to the navigation stack you have to assign the sharedData object in your first view controller to sharedData in your second view controller.
in your FirstStepViewController.m add:
[varSecondViewController sharedData] = [self sharedData];
before:
[self.navigationController pushViewController:varSecondViewController
animated: YES];
Finally make sure you have connected all your outlets correctly in interface builder and everything should run perfectly then :)

Implementing delegate methods for modal view controller data transfer

I have a simple project to present a modal view controller and transfer back a string based on which button in the modal VC that gets pressed. I based it all on watching the Stanford class on iTunes U. It looks like I have everything correct, but I get a couple of compiler warnings.
First I get one called passing argument 1 of 'setDelegate:' from incompatible pointer type in TransferViewController.m
Second I get four warnings called Invalid receiver type 'id <MyModalViewControllerDelegate>*' but these aren't displayed in the build results area, rather next to the offending lines in MyModalViewController.m, both lines in each of the button actions.
Here's the code...
// TransferViewController.h
#import <UIKit/UIKit.h>
#import "MyModalViewController.h";
#interface TransferViewController : UIViewController <MyModalViewControllerDelegate> {
UILabel *label;
UIButton *button;
}
#property (nonatomic, retain) IBOutlet UILabel *label;
#property (nonatomic, retain) UIButton *button;
- (IBAction)updateText;
#end
// TransferViewController.m
#import "TransferViewController.h"
#implementation TransferViewController
#synthesize label;
#synthesize button;
- (IBAction)updateText {
MyModalViewController *myModalViewController = [[MyModalViewController alloc] init];
myModalViewController.delegate = self; // I get the warning here.
[self presentModalViewController:myModalViewController animated:YES];
[myModalViewController release];
}
- (void)myModalViewController:(MyModalViewController *)controller didFinishSelecting:(NSString *)selectedDog {
label.text = selectedDog;
[self dismissModalViewControllerAnimated:YES];
}
#end
// MyModalViewController.h
#import <UIKit/UIKit.h>
#protocol MyModalViewControllerDelegate;
#interface MyModalViewController : UIViewController {
UIButton *abby;
UIButton *zion;
id <MyModalViewControllerDelegate> delegate;
}
#property (assign) id <MyModalViewControllerDelegate> delegate;
- (IBAction)selectedAbby;
- (IBAction)selectedZion;
#end
#protocol MyModalViewControllerDelegate <NSObject>
#optional
- (void)myModalViewController:(MyModalViewController *)controller didFinishSelecting:(NSString *)selectedDog;
#end
// MyModalViewController.m
#import "MyModalViewController.h"
#implementation MyModalViewController
#synthesize delegate;
- (IBAction)selectedAbby {
if ([self.delegate respondsToSelector:#selector (myModalViewController:didFinishSelecting:)]) {
[self.delegate myModalViewController:self didFinishSelecting:#"Abby"];
}
}
- (IBAction)selectedZion {
if ([self.delegate respondsToSelector:#selector (myModalViewController:didFinishSelecting:)]) {
[self.delegate myModalViewController:self didFinishSelecting:#"Zion"];
}
}
Get rid of those *s after id <something> and before delegate.
So make this
id <MyModalViewControllerDelegate> *delegate;
this
id <MyModalViewControllerDelegate> delegate;

How to handle Objective-C protocols that contain properties?

I've seen usage of Objective-C protocols get used in a fashion such as the following:
#protocol MyProtocol <NSObject>
#required
#property (readonly) NSString *title;
#optional
- (void) someMethod;
#end
I've seen this format used instead of writing a concrete superclass that subclasses extend. The question is, if you conform to this protocol, do you need to synthesize the properties yourself? If you're extending a superclass, the answer is obviously no, you do not need to. But how does one deal with properties that a protocol requires to conform to?
To my understanding, you still need to declare the instance variables in the header file of an object that conforms to a protocol that requires these properties. In that case, can we assume that they're just a guiding principle? CLearly the same isn't the case for a required method. The compiler will slap your wrist for excluding a required method that a protocol lists. What's the story behind properties though?
Here's an example that generates a compile error (Note: I've trimmed the code which doesn't reflect upon the problem at hand):
MyProtocol.h
#protocol MyProtocol <NSObject>
#required
#property (nonatomic, retain) id anObject;
#optional
TestProtocolsViewController.h
- (void)iDoCoolStuff;
#end
#import <MyProtocol.h>
#interface TestProtocolsViewController : UIViewController <MyProtocol> {
}
#end
TestProtocolsViewController.m
#import "TestProtocolsViewController.h"
#implementation TestProtocolsViewController
#synthesize anObject; // anObject doesn't exist, even though we conform to MyProtocol.
- (void)dealloc {
[anObject release]; //anObject doesn't exist, even though we conform to MyProtocol.
[super dealloc];
}
#end
The protocol is just telling everyone that knows about your class through the protocol, that the property anObject will be there. Protocols are not real, they have no variables or methods themselves - they only describe a specific set of attributes that is true about your class so that objects holding references to them can use them in specific ways.
That means in your class that conforms to your protocol, you have to do everything to make sure anObject works.
#property and #synthesize are at heart two mechanisms that generate code for you. #property is just saying there will be a getter (and/or setter) method for that property name. These days #property alone is enough to also have methods and a storage variable created for you by the system (you used to have to add #sythesize). But you have to have something to access and store the variable.
Here's an example of mine that works perfectly, the protocol definition first of all:
#class ExampleClass;
#protocol ExampleProtocol
#required
// Properties
#property (nonatomic, retain) ExampleClass *item;
#end
Below is a working example of a class supporting this protocol:
#import <UIKit/UIKit.h>
#import "Protocols.h"
#class ExampleClass;
#interface MyObject : NSObject <ExampleProtocol> {
// Property backing store
ExampleClass *item;
}
#implementation MyObject
// Synthesize properties
#synthesize item;
#end
all you have to do really is to drop a
#synthesize title;
in your implementation and you should be all set. it works the same way as just putting the property in your class interface.
Edit:
You may want to do this more specifically:
#synthesize title = _title;
This will fall in line with how xcode's automatic synthesis creates properties and ivars if you use auto-synthesis, so that way if your class has properties from a protocol and a class, some of your ivars won't have the different format which could impact readability.
Suppose I have MyProtocol that declares a name property, and MyClass that conforms to this protocol
Things worth noted
The identifier property in MyClass declares and generates getter, setter and backing _identifier variable
The name property only declares that MyClass has a getter, setter in the header. It does not generate getter, setter implementation and backing variable.
I can’t redeclare this name property, as it already declared by the protocol. Do this will yell an error
#interface MyClass () // Class extension
#property (nonatomic, strong) NSString *name;
#end
How to use property in protocol
So to use MyClass with that name property, we have to do either
Declare the property again (AppDelegate.h does this way)
#interface MyClass : NSObject <MyProtocol>
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSString *identifier;
#end
Synthesize ourself
#implementation MyClass
#synthesize name;
#end
Example: 2 classes (Person and Serial) want use service of Viewer... and must conform to ViewerProtocol. viewerTypeOfDescription is a mandatory property subscriber classes must conform.
typedef enum ViewerTypeOfDescription {
ViewerDataType_NSString,
ViewerDataType_NSNumber,
} ViewerTypeOfDescription;
#protocol ViewerProtocol
#property ViewerTypeOfDescription viewerTypeOfDescription;
- (id)initConforming;
- (NSString*)nameOfClass;
- (id)dataRepresentation;
#end
#interface Viewer : NSObject
+ (void) printLargeDescription:(id <ViewerProtocol>)object;
#end
#implementation Viewer
+ (void) printLargeDescription:(id <ViewerProtocol>)object {
NSString *data;
NSString *type;
switch ([object viewerTypeOfDescription]) {
case ViewerDataType_NSString: {
data=[object dataRepresentation];
type=#"String";
break;
}
case ViewerDataType_NSNumber: {
data=[(NSNumber*)[object dataRepresentation] stringValue];
type=#"Number";
break;
}
default: {
data=#"";
type=#"Undefined";
break;
}
}
printf("%s [%s(%s)]\n",[data cStringUsingEncoding:NSUTF8StringEncoding],
[[object nameOfClass] cStringUsingEncoding:NSUTF8StringEncoding],
[type cStringUsingEncoding:NSUTF8StringEncoding]);
}
#end
/* A Class Person */
#interface Person : NSObject <ViewerProtocol>
#property NSString *firstname;
#property NSString *lastname;
#end
#implementation Person
// >>
#synthesize viewerTypeOfDescription;
// <<
#synthesize firstname;
#synthesize lastname;
// >>
- (id)initConforming {
if (self=[super init]) {
viewerTypeOfDescription=ViewerDataType_NSString;
}
return self;
}
- (NSString*)nameOfClass {
return [self className];
}
- (NSString*) dataRepresentation {
if (firstname!=nil && lastname!=nil) {
return [NSString stringWithFormat:#"%# %#", firstname, lastname];
} else if (firstname!=nil) {
return [NSString stringWithFormat:#"%#", firstname];
}
return [NSString stringWithFormat:#"%#", lastname];
}
// <<
#end
/* A Class Serial */
#interface Serial : NSObject <ViewerProtocol>
#property NSInteger amount;
#property NSInteger factor;
#end
#implementation Serial
// >>
#synthesize viewerTypeOfDescription;
// <<
#synthesize amount;
#synthesize factor;
// >>
- (id)initConforming {
if (self=[super init]) {
amount=0; factor=0;
viewerTypeOfDescription=ViewerDataType_NSNumber;
}
return self;
}
- (NSString*)nameOfClass {
return [self className];
}
- (NSNumber*) dataRepresentation {
if (factor==0) {
return [NSNumber numberWithInteger:amount];
} else if (amount==0) {
return [NSNumber numberWithInteger:0];
}
return [NSNumber numberWithInteger:(factor*amount)];
}
// <<
#end
int main(int argc, const char * argv[])
{
#autoreleasepool {
Person *duncan=[[Person alloc]initConforming];
duncan.firstname=#"Duncan";
duncan.lastname=#"Smith";
[Viewer printLargeDescription:duncan];
Serial *x890tyu=[[Serial alloc]initConforming];
x890tyu.amount=1564;
[Viewer printLargeDescription:x890tyu];
NSObject *anobject=[[NSObject alloc]init];
//[Viewer printLargeDescription:anobject];
//<< compilator claim an issue the object does not conform to protocol
}
return 0;
}
An other Example with Protocol inheritance over subClassing
typedef enum {
LogerDataType_null,
LogerDataType_int,
LogerDataType_string,
} LogerDataType;
#protocol LogerProtocol
#property size_t numberOfDataItems;
#property LogerDataType dataType;
#property void** data;
#end
#interface Loger : NSObject
+ (void) print:(id<LogerProtocol>)object;
#end
#implementation Loger
+ (void) print:(id<LogerProtocol>)object {
if ([object numberOfDataItems]==0) return;
void **data=[object data];
for (size_t i=0; i<[object numberOfDataItems]; i++) {
switch ([object dataType]) {
case LogerDataType_int: {
printf("%d\n",(int)data[i]);
break;
}
case LogerDataType_string: {
printf("%s\n",(char*)data[i]);
break;
}
default:
break;
}
}
}
#end
// A Master Class
#interface ArrayOfItems : NSObject <LogerProtocol>
#end
#implementation ArrayOfItems
#synthesize dataType;
#synthesize numberOfDataItems;
#synthesize data;
- (id)init {
if (self=[super init]) {
dataType=LogerDataType_null;
numberOfDataItems=0;
}
return self;
}
#end
// A SubClass
#interface ArrayOfInts : ArrayOfItems
#end
#implementation ArrayOfInts
- (id)init {
if (self=[super init]) {
self.dataType=LogerDataType_int;
}
return self;
}
#end
// An other SubClass
#interface ArrayOfStrings : ArrayOfItems
#end
#implementation ArrayOfStrings
- (id)init {
if (self=[super init]) {
self.dataType=LogerDataType_string;
}
return self;
}
#end
int main(int argc, const char * argv[])
{
#autoreleasepool {
ArrayOfInts *arr=[[ArrayOfInts alloc]init];
arr.data=(void*[]){(int*)14,(int*)25,(int*)74};
arr.numberOfDataItems=3;
[Loger print:arr];
ArrayOfStrings *arrstr=[[ArrayOfStrings alloc]init];
arrstr.data=(void*[]){(char*)"string1",(char*)"string2"};
arrstr.numberOfDataItems=2;
[Loger print:arrstr];
}
return 0;
}
The variable, anObject, needs to be defined in your TestProtocolsViewController class definition, the protocol is just informing you that it should be there.
The compiler errors are telling you the truth - the variable doesn't exist. #properties are just helpers after all.