ocjective-c Obtain return value from public method
-
17-06-2021 - |
سؤال
I'm pretty new to objective-C (and C in general) and iPhone development and am coming from the java island, so there are some fundamentals that are quite tough to learn for me.
I'm diving right into iOS5 and want to use storyboards.
For now I am trying to setup a list in a UITableViewController
that will be filled with values returned by a web service in the future. For now, I just want to generate some mock objects and show their names in the list to be able to proceed.
Coming from java, my first approach would be to create a new Class that provides a global accessible method to generate some objects for my list:
#import <Foundation/Foundation.h>
@interface MockObjectGenerator : NSObject
+(NSMutableArray *) createAndGetMockProjects;
@end
Implementation is...
#import "MockObjectGenerator.h"
// Custom object with some fields
#import "Project.h"
@implementation MockObjectGenerator
+ (NSMutableArray *) createAndGetMockObjects {
NSMutableArray *mockProjects = [NSMutableArray alloc];
Project *project1 = [Project alloc];
Project *project2 = [Project alloc];
Project *project3 = [Project alloc];
project1.name = @"Project 1";
project2.name = @"Project 2";
project3.name = @"Project 3";
[mockProjects addObject:project1];
[mockProjects addObject:project2];
[mockProjects addObject:project3];
// missed to copy this line on initial question commit
return mockObjects;
}
And here is my ProjectTable.h that is supposed to control my ListView
#import <UIKit/UIKit.h>
@interface ProjectsTable : UITableViewController
@property (strong, nonatomic) NSMutableArray *projectsList;
@end
And finally ProjectTable.m
#import "ProjectsTable.h"
#import "Project.h"
#import "MockObjectGenerator.h"
@interface ProjectsTable {
@synthesize projectsList = _projectsList;
-(id)initWithStyle:(UITableViewStyle:style {
self = [super initWithStyle:style];
if (self) {
_projectsList = [[MockObjectGenerator createAndGetMockObjects] copy];
}
return self;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// only one section for all
return 1;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(@"%d entries in list", _projectsList.count);
return _projectsList.count;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// the identifier of the lists prototype cell is set to this string value
static NSString *CellIdentifier = @"projectCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Project *project = [_projectsList objectAtIndex:indexPath.row];
cell.textLabel.text = project.name
return cell;
}
So while I think everything is correctly set, I expect the tableView to show my three mock objects in its rows. But it stays empty and the NSLog
method prints "0 entries in list" into the console. So what am I doing wrong?
Any help is appreciated.
Best regards Felix
Update 1: missed to copy the two return statements into this box ("return mockObjects" and "return cell") which were already in my code, now inserted.
المحلول
You have at least two problems in your code:
In
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
You are supposed to return a valid UITableViewCell
(just return cell;
)
You should also init the objects you allocate:
NSMutableArray *mockProjects = [NSMutableArray alloc];
Project *project1 = [Project alloc];
Project *project2 = [Project alloc];
Project *project3 = [Project alloc];
To do so write mockProjects = [[NSMutableArray alloc]init];
and same for the Project
objects.
In the method you also need to return the object you create: return mockProjects;
I would strongly recommend that you check up on the Automatic reference Counting system, or try to learn the good ol' fashioned memory management model of iOS. It is very different from the Java way of doing things.
نصائح أخرى
You're missing
return mockProjects;
in your method
+ (NSMutableArray *) createAndGetMockObjects {
EDIT
Also, like everyone else is pointing out, you need to make sure to call init
on all of the objects you are allocating. Simply allocating it does not initialize the object, and you can't really use it until you do so
First: always call alloc
and init
to create an object.
Second: You don't return the mutable array in your class method.
Add a return mockProjects;
statement at the end