I'm just a beginner in Cocoa developing for Snow Leopard and I have problem with editing values in data array that displayed in NSTableView.
I tried to edit some property of my object in -tableView:setObjectValue:forTableColumn:row: and I have EXC_BAD_ACCESS after this.
My NSTableView contains one column with NSButtonCell cells and this column have identifier 'checked'.
My code is simple and looks like this:
#interface MyObj: NSObject {
BOOL checked;
}
#property (assign) BOOL checked;
#end
#imlpementation MyObj
#synthesize checked;
#end
#interface MyAppDelegate: NSObject <NSApplicationDelegate, NSTableViewDelegate, NSTableViewDataSource> {
NSMutableArray *data;
NSTableView *table;
}
#property (assign) IBOutlet NSTableView *table;
- (NSInteger) numberOfRowsInTableView:(NSTableView *)aTableView;
- (id) tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex;
- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex;
#end
#implementation MyAppDelegate
#synthesize table;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
data = [[NSMutableArray array] retain];
// some code that add few objects to data
// each object is instance of MyObj and I call alloc+init+retain for each
// ...
[table reloadData];
}
- (void)dealloc {
[data release];
[super dealloc];
}
- (NSInteger) numberOfRowsInTableView:(NSTableView *)aTableView {
return (data == nil ? 0 : [data count]);
}
- (id) tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {
MyObj *obj;
obj = [data objectAtIndex:rowIndex];
NSString *identifier;
identifier = [aTableColumn identifier];
return [obj performSelector:NSSelectorFromString(identifier)];
}
- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {
MyObj *obj;
obj = [data objectAtIndex:rowIndex];
NSString *identifier;
identifier = [aTableColumn identifier];
if ([identifier isEqualTo:#"checked"]) {
BOOL value = [anObject boolValue];
obj.checked = value;
[data replaceObjectAtIndex:rowIndex withObject:obj];
}
[table reloadData];
}
#end
And I have raised objc_msgSend_vtable5 from -[NSButtonCell setObjectValue] method.
I found solution for my problem. I changed BOOL checked to NSNumber *checked.
- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {
MyObj *obj = (MyObj *)[data objectAtIndex:rowIndex];
NSString *identifier;
identifier = [aTableColumn identifier];
if ([identifier isEqualTo:#"checked"]) {
[obj setValue:[[NSNumber numberWithBool:[anObject boolValue]] retain] forKey:[aTableColumn identifier]];
}
[table reloadData];
}
And all works fine right now. I hope it helps someone.
Related
I have done this :
That is NSOutlineView with two columns, first column is TextCell and on second column I drag and drop Check Box Cell.
Now, I set true all rows so :
-(id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *) tableColumn byItem:(id)item {
if ([[tableColumn identifier] isEqualToString:#"name"]) {
return [item name];
} else if ([[tableColumn identifier] isEqualToString:#"sel"]) {
return #"1"; //for NSOnState
//return #"0"; //for NSOffState
}
}
Now I want that when user click on checkbox it go to NSOffState and I try inside method so :
-(void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
[item setSel:NSOffState];
}
but it don't go, how can i do ?
Help me !!!
#import
#interface AppDelegate : NSObject {
NSMutableArray *array;
}
#property (assign) IBOutlet NSWindow *window;
#end
#import "AppDelegate.h"
#implementation AppDelegate
#synthesize window = _window;
- (void)dealloc
{
[super dealloc];
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
}
-(void)awakeFromNib
{
array=[[[NSMutableArray alloc]init]autorelease];
NSMutableDictionary *dc=[NSMutableDictionary dictionary];
BOOL test=YES;
NSNumber *num=[NSNumber numberWithBool:test];
[dc setObject:num forKey:#"sel"];
[dc setObject:#"name" forKey:#"name"];
[array addObject:dc];
//[self setArray:self.array];
}
- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
{
return [array objectAtIndex:index];
}
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
{
return NO;
}
- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
{
return [array count];
}
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
if ([[tableColumn identifier] isEqualToString:#"name"])
{
/*
NSString *str=[item objectForKey:#"name"];
NSLog(#"name=%#",str);*/
return #"name"; //str;
}
else if ([[tableColumn identifier] isEqualToString:#"sel"])
{
/*
NSString *str=[item objectForKey:#"sel"];
NSNumber *num=[NSNumber numberWithBool:[str boolValue]];
NSLog(#"sel=%#",num);*/
return #"0"; //num;
}
else
{
return nil;
}
}
- (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
[item setValue:object forKey:[tableColumn identifier]];
}
#end
I'm trying to save an array of objects with NSCoding when the home button or program is exited, but nothing seems to happen.
What am I doing wrong????
//Fieldbook.h custom object
#interface FieldBook : NSObject <NSCoding>
{
NSString *title;
NSDate *date;
}
#property (nonatomic, retain) NSString *title;
#property (nonatomic, retain) NSDate *date;
-(id) init:(NSString *)aTitle;
- (NSString *) description;
#end
//Fieldbook.m
#import "FieldBook.h"
#implementation FieldBook
#synthesize title, date;
-(id) init:(NSString *)aTitle
{
title = aTitle;
return self;
}
- (NSString *) description
{
NSString *desc = [NSString stringWithFormat:#"%#\n", title];
return desc;
}
- (id)initWithCoder:(NSCoder *)decoder
{
if (self = [super init])
{
self.title = [decoder decodeObjectForKey:#"title"];
self.date = [decoder decodeObjectForKey:#"date"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:title forKey:#"time"];
[encoder encodeObject:date forKey:#"date"];
}
#end
//ViewController.h
#interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UIAlertViewDelegate>
#property (weak, nonatomic) IBOutlet UITableView *myTableView;
#property (strong, nonatomic) NSMutableArray *fieldBooks;
#property (nonatomic, retain) UITextField *projectName;
- (NSString *)dataFilePath;
#end
//ViewController.m
#import "FieldBook.h"
#import "ViewController.h"
#implementation ViewController
#synthesize myTableView, fieldBooks, projectName;
- (void)viewDidLoad
{
// Do any additional setup after loading the view, typically from a nib.
[super viewDidLoad];
if(fieldBooks == nil)
fieldBooks = [[NSMutableArray alloc]init];
NSMutableArray *tempArray = [NSKeyedUnarchiver unarchiveObjectWithFile:[self dataFilePath]];
[self.fieldBooks addObjectsFromArray:tempArray];
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationWillResignActive:)
name:UIApplicationWillResignActiveNotification
object:app];
[self.myTableView reloadData];
//Set title
self.title = #"FieldBooks";
//Add edit button
self.navigationItem.leftBarButtonItem = self.editButtonItem;
//Add the add button
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(insertNewObject)];
self.navigationItem.rightBarButtonItem = addButton;
}
- (void)applicationWillResignActive:(NSNotification *)notification
{
[NSKeyedArchiver archiveRootObject:self.fieldBooks toFile:[self dataFilePath]];
}
- (NSString *)dataFilePath
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:#"datafile"];
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
[myTableView setEditing:editing animated:animated];
}
- (void)insertNewObject
{
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:#"Enter name"
message:#""
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"OK", nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
projectName = [alert textFieldAtIndex:0];
[alert show];
}
#pragma mark - UIAlertView delegate method
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
//Only perform if OK button is pressed
if (buttonIndex == 1)
{
FieldBook *fb = [[FieldBook alloc] init:(NSString *)projectName.text];
[fieldBooks addObject:fb];
[myTableView reloadData];
NSLog(#"FieldBook created: %#", fb);
}
}
#pragma mark - UITableView Datasource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [fieldBooks count];
}
- (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];
}
FieldBook *fbName = [self.fieldBooks objectAtIndex:[indexPath row]];
cell.textLabel.text = fbName.title;
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
//remove from NSMutable array
[fieldBooks removeObjectAtIndex:indexPath.row];
//remove from table view
[myTableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
#end
I have a problem in getting a method to work, and I am totally confused.
I am unable to hand over a string as a variable for my method.
I call the function even with the string, no variable currently.
Engine *myEngine = [Engine sharedInstance];
[myEngine getContentArrayFromEngine:#"zumbra"];
My method
-(NSMutableArray*) getContentArrayFromEngine:(NSString *)catName{
NSMutableSet* categorieContent = [[NSMutableSet alloc] init];
NSLog(#"Catname:%#", catName);
//some more code
}
NSLOG output
2011-12-18 18:49:44.165 Zitate[77224:15203] Catname:(null)
Why is catName empty ???
edit1: the complete code
ThirdViewController.m
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString* myTempCatname;
myTempCatname = cell.textLabel.text;
// NSLog(#"test select %#", myTempCatname);
DetailViewController *detailVC = [self.storyboard instantiateViewControllerWithIdentifier:#"detailzitat"];
[self.navigationController pushViewController:detailVC animated:YES];
Engine *myEngine = [Engine sharedInstance];
[myEngine getContentArrayFromEngine:myTempCatname];
}
and in the engine.m
-(NSMutableArray*) getContentArrayFromEngine:(NSString *)catName{
NSMutableSet* categorieContent = [[NSMutableSet alloc] init];
NSLog(#"Übergebener Catname:%#", catName);
// catName=#"zumbra";
// NSLog(#"Inhalt InhalteFromWeb:%#", InhalteFromWeb);
NSLog(#"Catname:%#", catName);
unsigned count = [InhalteFromWeb count];
while (count--) {
NSLog(#"count %d %#", count, [[InhalteFromWeb objectAtIndex:count] objectForKey:CATEGORY]);
if([[[InhalteFromWeb objectAtIndex:count] objectForKey:CATEGORY] isEqualToString:catName]) {
[categorieContent addObject:[InhalteFromWeb objectAtIndex:count]];
NSLog(#"Row %d has Content%#",count, [InhalteFromWeb objectAtIndex:count]);
}
}
NSLog(#"Inhalt Category:%#", categorieContent);
NSArray* tempAr = [[NSArray alloc] initWithArray:[categorieContent allObjects]];
return [NSMutableArray arrayWithArray:tempAr];
}
EDIT2:
Ok, even the hint with the catName did not work. so I have changed my code a little bit.
I have an array with a category, title, content, author, image for each row
I would like to do two things
1) get a unique list of all categories (its working fine)
2) when tapping on one of these categories , open a detailView , show the first element of this category, jump to previous and next item in category by swiping around.
For this, I am going to SET the category I have chosen
First try was to handover in the method, which did not work.
Now I though, SET the category in my engine.h and when displaying the single item, get the array for this category back.
but again, the value of the category is not stored.
ThirdViewController.h
#import <UIKit/UIKit.h>
#import "SecondViewController.h"
#interface ThirdViewController : UIViewController<UITableViewDelegate, UITableViewDataSource> {
NSMutableArray* CategoryList;
}
#property (nonatomic, retain) NSMutableArray* CategoryList;
#end
ThirdViewController.m
#import "ThirdViewController.h"
#import "engine.h"
#import "DetailViewController.h"
#implementation ThirdViewController
#synthesize CategoryList;
- (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.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
Engine *myEngine = [Engine sharedInstance];
CategoryList = [myEngine getCategories];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [CategoryList count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier =#"Cell";
UITableViewCell *cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [CategoryList objectAtIndex:indexPath.row];
return cell;
}
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString* myTempCatname;
myTempCatname = cell.textLabel.text;
DetailViewController *detailVC = [self.storyboard instantiateViewControllerWithIdentifier:#"detailzitat"];
[self.navigationController pushViewController:detailVC animated:YES];
Engine *myEngine = [Engine sharedInstance];
[myEngine setCategName:myTempCatname];
NSLog(#"Aufruf %#", myTempCatname);
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
DetailViewController.h
#import <UIKit/UIKit.h>
#import <MessageUI/MFMailComposeViewController.h>
#import "engine.h"
#interface DetailViewController : UIViewController<MFMailComposeViewControllerDelegate> {
IBOutlet UILabel *authorLabel;
IBOutlet UILabel *categoryLabel;
IBOutlet UILabel *titleLabel;
IBOutlet UITextView *contentTextView;
NSString *authorText, *contentText, *categoryText, *titleText, *imageText, *catName;
NSMutableArray *contentArray;
}
#property (nonatomic, retain) IBOutlet UITextView *contentTextView;
#property (nonatomic, retain) IBOutlet UILabel *authorLabel;
#property (nonatomic, retain) IBOutlet UILabel *categoryLabel;
#property (nonatomic, retain) IBOutlet UILabel *titleLabel;
#property (nonatomic, retain) NSString *authorText, *contentText, *categoryText, *titleText, *imageText, *catName;
#property (nonatomic, retain) NSMutableArray *contentArray;
-(IBAction)vorher:(id)sender;
-(IBAction)nachher:(id)sender;
#end
DetailViewController.m
#import "DetailViewController.h"
#implementation DetailViewController
#synthesize contentTextView;
#synthesize authorText, contentText, categoryText, titleText, imageText;
#synthesize authorLabel, categoryLabel, titleLabel;
#synthesize contentArray;
#synthesize catName;
int contentIndex;
int contentMax;
- (IBAction)swipeDetected:(UIGestureRecognizer *)sender {
NSLog(#"Right Swipe detected");
}
-(IBAction) vorher:(id)sender {
NSLog(#"-----VORHER Button gedrückt-------");
if (contentIndex==0) {contentIndex=contentMax-1;}
else {contentIndex--;}
titleText = [[contentArray objectAtIndex:contentIndex] objectForKey:TITLE];
authorText= [[contentArray objectAtIndex:contentIndex] objectForKey:AUTHOR];
contentText= [[contentArray objectAtIndex:contentIndex] objectForKey:CONTENT];
authorLabel.text=authorText;
titleLabel.text=titleText;
contentTextView.text=contentText;
}
-(IBAction) nachher:(id)sender {
NSLog(#"-----Nachher Button gedrückt-------");
if (contentIndex==contentMax-1) {contentIndex=0;}
else {contentIndex++;}
titleText = [[contentArray objectAtIndex:contentIndex] objectForKey:TITLE];
authorText= [[contentArray objectAtIndex:contentIndex] objectForKey:AUTHOR];
contentText= [[contentArray objectAtIndex:contentIndex] objectForKey:CONTENT];
authorLabel.text=authorText;
titleLabel.text=titleText;
contentTextView.text=contentText;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
Engine *myEngine = [Engine sharedInstance];
contentArray = [myEngine getContentArrayFromEngine];
contentMax = [contentArray count];
UISwipeGestureRecognizer *swipeRecognizerRight =
[[UISwipeGestureRecognizer alloc]
initWithTarget:self
action:#selector(vorher:)];
swipeRecognizerRight.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:swipeRecognizerRight];
UISwipeGestureRecognizer *swipeRecognizerLeft =
[[UISwipeGestureRecognizer alloc]
initWithTarget:self
action:#selector(nachher:)];
swipeRecognizerLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:swipeRecognizerLeft];
titleText = [[contentArray objectAtIndex:contentIndex] objectForKey:TITLE];
authorText= [[contentArray objectAtIndex:contentIndex] objectForKey:AUTHOR];
contentText= [[contentArray objectAtIndex:contentIndex] objectForKey:CONTENT];
authorLabel.text=authorText;
titleLabel.text=titleText;
contentTextView.text=contentText;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
engine.h
//#import
#define AUTHOR #"author"
#define CATEGORY #"cat"
#define CONTENT #"content"
#define IMAGE #"image"
#define TITLE #"title"
#interface Engine : NSObject {
NSMutableArray* InhalteFromWeb;
NSInteger maxAnzahlInhalte;
NSString* categNameStorage;
}
+ (Engine *) sharedInstance;
- (NSMutableArray*) getZitateArrayFromEngine;
- (NSInteger) getMaxAnzahlZitateFromEngine;
- (NSString*) getAutor:(NSInteger)pos;
- (NSString*) getZitat:(NSInteger)pos;
- (NSString*) getAuthor:(NSInteger)pos;
- (NSString*) getCategory:(NSInteger)pos;
- (NSString*) getContent:(NSInteger)pos;
- (NSString*) getImage:(NSInteger)pos;
- (NSString*) getTitle:(NSInteger)pos;
-(NSMutableArray*) getContentArrayFromEngine;
-(void) setCategName:(NSString *) categNameVariable;
-(NSString*) getCategName;
-(NSMutableArray*) getCategories;
#end
engine.m
#import "Engine.h"
#implementation Engine
static Engine *_sharedInstance;
- (id) init
{
if (self = [super init])
{
// custom initialization
//Beginn my code
NSURL *url = [NSURL URLWithString:#"http://www.*/iMotivate.plist"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if( theConnection )
{
InhalteFromWeb = [[NSMutableArray alloc] initWithContentsOfURL:url];
maxAnzahlInhalte = [InhalteFromWeb count];
}
else
{
NSLog(#"Connection failed");
}
}
return self;
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
// NSLog(#"Recieving Response...");
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// NSLog(#"Recieving Data...");
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message : #"An error has occured.Please verify your internet connection."
delegate:nil
cancelButtonTitle :#"OK"
otherButtonTitles :nil];
[alert show];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// NSLog(#"DONE. Received Quotes: %d", maxAnzahlZitate);
}
// ###########
+ (Engine *) sharedInstance
{
if (!_sharedInstance)
{
_sharedInstance = [[Engine alloc] init];
}
return _sharedInstance;
}
// Getter and Setter for WebArray
- (NSMutableArray*) getZitateArrayFromEngine{
return InhalteFromWeb;
}
- (NSInteger) getMaxAnzahlZitateFromEngine{
return maxAnzahlInhalte;
}
- (NSString*) getAutor:(NSInteger)pos{
return [[InhalteFromWeb objectAtIndex:pos] objectForKey:AUTHOR];
}
- (NSString*) getZitat:(NSInteger)pos{
return [[InhalteFromWeb objectAtIndex:pos] objectForKey:CONTENT];
}
// #######
- (NSString*) getAuthor:(NSInteger)pos{
return [[InhalteFromWeb objectAtIndex:pos] objectForKey:AUTHOR];
}
- (NSString*) getCategory:(NSInteger)pos{
return [[InhalteFromWeb objectAtIndex:pos] objectForKey:CATEGORY];
}
- (NSString*) getContent:(NSInteger)pos{
return [[InhalteFromWeb objectAtIndex:pos] objectForKey:CONTENT];
}
- (NSString*) getImage:(NSInteger)pos{
return [[InhalteFromWeb objectAtIndex:pos] objectForKey:IMAGE];
}
- (NSString*) getTitle:(NSInteger)pos{
return [[InhalteFromWeb objectAtIndex:pos] objectForKey:TITLE];
}
-(NSArray*) getCategories {
NSMutableSet* categorieSet = [[NSMutableSet alloc] init];
unsigned count = [InhalteFromWeb count];
while (count--) {
NSString *tempString;
tempString=[[InhalteFromWeb objectAtIndex:count] objectForKey:CATEGORY];
// NSLog(#"tempString %#", tempString );
[categorieSet addObject:tempString];
}
// NSLog(#"categories from engine %#", categorieSet);
NSArray* tempAr = [[[NSArray alloc] initWithArray:[categorieSet allObjects]]sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
return [NSMutableArray arrayWithArray:tempAr];
}
-(void) setCategName:(NSString *) categNameVariable
{ NSLog(#"categNameStorage 2%#",categNameStorage);
categNameStorage=categNameVariable;
NSLog(#"setCategName 1 %#",categNameVariable);
NSLog(#"categNameStorage 2%#",categNameStorage);
}
-(NSString*) getCategName {
return categNameStorage;
}
-(NSMutableArray*) getContentArrayFromEngine{
NSMutableSet* categorieContent = [[NSMutableSet alloc] init];
NSLog(#"Übergebener Catname:%#", categNameStorage);
// NSLog(#"Inhalt InhalteFromWeb:%#", InhalteFromWeb);
unsigned count = [InhalteFromWeb count];
while (count--) {
// NSLog(#"count %d %#", count, [[InhalteFromWeb objectAtIndex:count] objectForKey:CATEGORY]);
if([[[InhalteFromWeb objectAtIndex:count] objectForKey:CATEGORY] isEqualToString:categNameStorage]) {
[categorieContent addObject:[InhalteFromWeb objectAtIndex:count]];
// NSLog(#"Row %d has Content%#",count, [InhalteFromWeb objectAtIndex:count]);
}
}
// NSLog(#"Inhalt Category:%#", categorieContent);
NSArray* tempAr = [[NSArray alloc] initWithArray:[categorieContent allObjects]];
return [NSMutableArray arrayWithArray:tempAr];
}
#end
There has to be a variable conflict with 'catName' in your view controller. I'm not sure why the view controller would be in scope, but I bet if you change your parameter to "inCatName" it will be fine. It's good to use naming conventions like that for this reason.
With the delegate and datasource connections made, I have the following controller:
#import <Foundation/Foundation.h>
#interface KextTable : NSObject <NSTableViewDataSource> {
#private
NSArray *klist;
}
- (int)numberOfRowsInTableView:(NSTableView *)tableView;
- (id)tableView:(NSTableView *)tableView
objectValueForTableColumn:(NSTableColumn *)tableColumn
row:(int)row;
#end
and
#import "KextTable.h"
#implementation KextTable
- (id)init
{
self = [super init];
if (self) {
}
return self;
}
-(void) awakeFromNib
{
klist = [[NSArray alloc] init];
klist = [NSArray arrayWithObjects: #"1", #"2",
#"3", #"4", nil]; // debugging values only
}
- (void)dealloc
{
[super dealloc];
}
- (int)numberOfRowsInTableView:(NSTableView *)tableView
{
return [klist count];
}
- (id)tableView:(NSTableView *)tableView
objectValueForTableColumn:(NSTableColumn *)tableColumn
row:(int)row
{
return [klist objectAtIndex:row];
}
#end
And this code is crashing with EXC_BAD_ACCESS in my main interface control where the view is switched to the tab containing the table view. What is wrong?
(I know that connections are right, if I create the array in objectValueForTableColumn it works)
It's because the klist you're creating (the debug one) is using the constructor that autoreleases it. So you should add in:
klist = [[NSArray arrayWithObjects: #"1", #"2", #"3", #"4", nil] retain];
Be sure to note that in what you've done there's a memory leak (you create an NSArray and then re-assign the variable to something else...)
Here's my code:
test.h
#interface testAppDelegate : NSObject <NSApplicationDelegate> {
NSWindow *window;
IBOutlet NSTableView *test;
NSMutableArray *internalArray;
}
#property (assign) IBOutlet NSWindow *window;
#property (nonatomic, retain) NSTableView *test;
-(id) initWithArray: (NSArray*) objects;
-(int)numberOfRowsInTableView:(NSTableView *)aTableView;
-(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex;
-(void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex;
test.m (top pieces missing for simplicity's sake)
#synthesize window;
#synthesize test;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
PSClient *client = [PSClient applicationClient];
NSURL *url = [NSURL URLWithString:#"http://www.apple.com/main/rss/hotnews/hotnews.rss"];
PSFeed *feed = [client addFeedWithURL:url];
internalArray = [NSMutableArray array];
// Retrieve the entries as an unsorted enumerator
NSEnumerator *entries = [feed entryEnumeratorSortedBy: nil];
PSEntry *entry;
// Go through each entry and print out the title, authors, and content
while (entry = [entries nextObject]) {
[internalArray addObject:entry.title];
//NSLog(#"Entry Title:%#", entry.title);
//NSLog(#"Entry Authors:%#", entry.authorsForDisplay);
[test reloadData];
//NSLog(#"Entry Content:%#", entry.content.plainTextString);
}
}
-(int)numberOfRowsInTableView:(NSTableView *)aTableView{
NSLog(#"%#", [internalArray count]);
return [internalArray count];
}
-(id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
{
NSString *string = [internalArray objectAtIndex:rowIndex];
NSLog(#"%#", string);
// when I debug, I get same pointers with invalid data
// each object has "name" message
// this following line gives invalid pointer and
// it crashes
return string;
}
-(void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
{
NSString *string = [internalArray objectAtIndex:rowIndex];
NSLog(#"%#", string);
// when I debug, I get same pointers with invalid data
// each object has "name" message
// this following line gives invalid pointer and
// it crashes
return string;
}
#end
In IB I have the tableview (test) hooked up to the app delegate: test, datasource, and delegate
For some reason the table isn't displaying the data, and when I call [test reloadData]; the app crashes
Number one with a bullet - you don't retain internalArray after you create it. Use one of:
internalArray = [[NSMutableArray] alloc] init];
internalArray = [[NSMutableArray array] retain];
instead of what you currently have:
internalArray = [NSMutableArray array];
Also, I think you probably don't want %# for the format in this method:
-(int)numberOfRowsInTableView:(NSTableView *)aTableView{
NSLog(#"%#", [internalArray count]);
return [internalArray count];
}
That code will certainly (well, often) cause a crash when you do [tableView reloadData].
In applicationDidFinishLaunching:, you don't need to call reloadData every time you add an object to internalArray. Just do it once at the end of that loop.
Your implementation of setObjectValue:forTableColumn:row: also doesn't make sense. It should look more like this:
-(void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
{
NSLog(#"%#", anObject);
[internalArray replaceObjectAtIndex:rowIndex withObject:anObject];
}
Hopefully those are some ideas to get you started.