NSMutableArray initWithObjects Not Working - objective-c

Ey guys, I am having some problems adding NSURLs to an array and looping through them. Here are the relevant portions of my code:
RSS_ReaderAppDelegate.h:
#interface RSS_ReaderAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UINavigationController *navigationController;
NSDictionary *RSSFeeds;
NSMutableArray *RSSFeedURLs;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
#property (nonatomic, retain) NSDictionary *RSSFeeds;
#property (nonatomic, retain) NSMutableArray *RSSFeedURLs;
RSS_ReaderAppDelegate.m:
#implementation RSS_ReaderAppDelegate
#synthesize window;
#synthesize navigationController;
#synthesize RSSFeeds, RSSFeedURLs;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
NSURL *url1 = [[NSURL alloc] initWithString:#"http://<some url>"]; //real URL has been hidden
NSURL *url2 = [[NSURL alloc] initWithString:#"http://<some other url>"]; //real URL has been hidden
[RSSFeedURLs initWithObjects: url1, url2, nil];
[url1 release];
[url2 release];
for (NSURL *url in RSSFeedURLs) { //jumps right over this for loop
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
XMLParser *parser = [[XMLParser alloc] init];
[xmlParser setDelegate:parser];
//Start parsing the XML file.
BOOL success = [xmlParser parse];
if(success)
NSLog(#"No Errors");
else
NSLog(#"Error(s) encountered");
}//for
// Add the navigation controller's view to the window and display.
[window addSubview:navigationController.view];
[window makeKeyAndVisible];
return YES;
}
So [RSSFeedURLs initWithObjects: url1, url2, nil]; doesn't seem to actually do anything as when I run the debugger and type "po RSSFeedsURLs" it reports: "Cannot access memory at address 0x0", and thus the for loop is never entered. I have no idea why this is so, can anyone shed some light on this situation for me? Thanks in advance.

you want:
RSSFeedURLs = [[NSMutableArray alloc] initWithObjects: url1, url2, nil];
but you should want:
rssFeedURLs = [[NSMutableArray alloc] initWithObjects: url1, url2, nil];
Variables starting with capital letters lead to much confusion.

Related

Pulling coordinates for MapView annotations from MySQL database, but annotations aren't showing?

I'm trying to pull coordinates for my MapView from a MySQL database, but for some reason my coordinates just aren't showing up on the MapView?
See below my code.
MapViewController.h file
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#interface MapViewController : UIViewController <MKMapViewDelegate>
#property (nonatomic, strong) IBOutlet MKMapView *mapView;
#property (nonatomic, retain) NSMutableArray *dispensaries;
#property (nonatomic, retain) NSMutableData *data;
#end
MapViewController.m
#import "MapViewController.h"
#import "MapViewAnnotation.h"
#import "JSONKit.h"
#implementation MapViewController
#synthesize mapView;
#synthesize dispensaries;
#synthesize data;
#pragma mark - View lifecycle
- (void)viewDidLoad {
[super viewDidUnload];
NSLog(#"Getting Device Locations");
NSString *hostStr = #"http://stylerepublicmagazine.com/dispensaries.php";
NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:hostStr]];
NSString *serverOutput = [[NSString alloc] initWithData:dataURL encoding: NSASCIIStringEncoding];
NSLog(#"server output: %#", serverOutput);
NSMutableArray *array = [[[serverOutput objectFromJSONString] mutableCopy] autorelease];
dispensaries = [serverOutput objectFromJSONString];
NSLog(#"%#", [serverOutput objectFromJSONString]);
for (NSDictionary *dictionary in array) {
assert([dictionary respondsToSelector:#selector(objectForKey:)]);
CLLocationCoordinate2D coord = {[[dictionary objectForKey:#"lat"] doubleValue], [[dictionary objectForKey:#"lng"] doubleValue]};
MapViewAnnotation *ann = [[MapViewAnnotation alloc] init];
ann.title = [dictionary objectForKey:#"Name"];
ann.coordinate = coord;
[mapView addAnnotation:ann];
}
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
self.mapView.delegate = self;
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 800, 800);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = userLocation.coordinate;
point.title = #"You Are Here";
point.subtitle = #"Your current location";
[self.mapView addAnnotation:point];
}
MapViewAnnotation.h
#import <Foundation/Foundation.h>
#import <MapKit/MKAnnotation.h>
#import <CoreLocation/CoreLocation.h>
#interface MapViewAnnotation : NSObject <MKAnnotation> {
CLLocationCoordinate2D coordinate;
NSString *title;
NSString *subtitle;
}
#property (nonatomic, assign) CLLocationCoordinate2D coordinate;
#property (nonatomic, copy) NSString *title;
#property (nonatomic, copy) NSString *subtitle;
#end
MapViewAnnotation.m
#import "MapViewAnnotation.h"
#implementation MapViewAnnotation
#synthesize title, coordinate, subtitle;
-(void)dealloc{
[title release];
[super dealloc];
}
#end
this seems to be an issue with you expecting the wrong JSON:
You wrap the serverOutput in an array:
NSMutableArray *array = [NSMutableArray arrayWithObject:[serverOutput objectFromJSONString]];
You try to access a JKDictionary (Json Kit dictionary) WITCH is infact an array and therefore doesn't answer to objectForKey:
try to make sure:
for (NSDictionary *dictionary in array) {
assert([dictionary respondsToSelector:#selector(objectForKey:)]);
--
potential Solution
I believe your extra wrapping makes it bad. try:
NSMutableArray *array = [[[serverOutput objectFromJSONString] mutableCopy] autorelease];

iOS Passing (Retain) the value of an NSMutableArray to another NSMutableArray in another view

I'm using .XIB and without ARC. I'm passing the value of the NSMultableArray to another view, if I put [self presentModel...], it works, but if I call the AnotherView with a button the value of the NSMultableArray of the AnotherView is null!
AnotherView.h
#interface AnotherViewController : UIViewController<UITableViewDataSource, UITableViewDelegate>{
NSMutableArray *otherAnother;
NSMutableArray *arrayOfTheAnotherView;
}
#property (retain, nonatomic) IBOutlet UITableView *tableView;
#property (retain, nonatomic) NSMutableArray *arrayOfTheAnotherView;
AnotherView.m
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
otherAnother = [[NSMutableArray alloc]init];
otherAnother = [[NSMutableArray alloc]initWithArray:self.arrayOfTheAnotherView];
//    [otherAnother addObjectsFromArray:arrayOfTheAnotherView];
NSLog(#"%#", self.arrayOfTheAnotherView);
}
The NSLog has written "null"
CurrentView.h
#interface CurrentViewController : UIViewController {
NSMutableArray * arrayCurrentView;
AnotherViewController *superAnotherView;
}
#property (retain, nonatomic) AnotherViewController *superAnotherView;
CurrentView.m
#synthesize superAnotherView;
NSString *x = [[NSString alloc]initWithFormat:#"%#",[label text]];
arrayCurrentView = [[NSMutableArray alloc]init];
[arrayCurrentView retain];
[arrayCurrentView addObject:x];
self.superAnotherView = [[AnotherViewController alloc]initWithNibName:nil bundle:nil];
self.superAnotherView.arrayOfTheAnotherView = [[NSMutableArray alloc]init];
[self.superAnotherView.arrayOfTheAnotherView retain];
[self.superAnotherView.arrayOfTheAnotherView addObjectsFromArray:arrayCurrentView];
I don't know how to retain the value of the NSMultableArray, thanks the help.
It is how I call the AnotherView:
UIButton *buttonAnother = [UIButton buttonWithType:UIButtonTypeCustom]; [buttonAnother setTag:5]; [buttonAnother addTarget:self action:#selector(switchTabBar:) forControlEvents:UIControlEventTouchDown];
[tabBarViewController.view addSubview:buttonAnother];
- (IBAction)switchTabBar:(id)sender { switch ([(UIButton *)sender tag]) { case 5: [self.tabBarController setSelectedIndex:0]; break; }
These should not be necessary:
self.superAnotherView.arrayOfTheAnotherView = [[NSMutableArray alloc]init];
[self.superAnotherView.arrayOfTheAnotherView retain];
Properties are already initialized when the class is initialized.
In fact, your explicit retain lines shouldn't be necessary at all; you're not releasing them as far as I can see and just making the retain count 2 so that it has to be released twice.
I think there's something going on here that the methods and view controllers are not being called in the order you want, probably something to do with the tab bar.
I dicoverd! I'm using the MVC
A array of the APP delegate don't lost its value.
AppDelegate
NSMutableArray *arrayDelegate;
View.m
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication]delegate];
[appDelegate.arrayDelegatePedido addObject:#"title"]; //for example

An AppDelegate's property is unexpectedly set to null

First of all, I really appreciate your helps.
Well, I use three NSString objects in common in two views. And these view is segued by Embedded NavigationController, I mean I start programming with SingleView.
In AppDelegate.h, I write
#property (weak, nonatomic) NSString *crntURL;
#property (weak, nonatomic) NSString *crntTitle;
#property (weak, nonatomic) NSString *crntHTML;
for delegation.
And in the first view, I have a webview and write
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSString *url = [[NSString alloc] initWithString:[myWebView stringByEvaluatingJavaScriptFromString:#"document.URL"]];
NSString *title = [[NSString alloc] initWithString:[myWebView stringByEvaluatingJavaScriptFromString:#"document.title"]];
NSString *html = [[NSString alloc] initWithString:[myWebView stringByEvaluatingJavaScriptFromString:#"document.all[0].outerHTML"]];
appDelegate.crntTitle = nil;
appDelegate.crntTitle = [[NSString alloc] initWithString:title];
appDelegate.crntHTML = nil;
appDelegate.crntHTML = [[NSString alloc] initWithString:html];
appDelegate.crntURL = nil;
appDelegate.crntURL = [[NSString alloc] initWithString:url];
}
Here, when I put NSLog, the expected HTML source code is dumped.
And in the second view(a subclass of UIViewController), I write
- (void)viewDidLoad
{
// Do any additional setup after loading the view.
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
sourceHTML.text = appDelegate.crntHTML;
NSLog( #"%#", appDelegate.crntHTML );
NSLog( #"%#", appDelegate.crntURL );
NSLog( #"%#", appDelegate.crntTitle );
[super viewDidLoad];
}
and only crntHTML is unexpectedly set to null while crntURL and crntTitle keep values.
Do you have any ideas?
Thank you in advance.
Masaru
You've declared your properties in the app delegate as weak.
Using ARC, an object will be released and set to nil if there's no strong reference to it.
I could imagine you're referencing the title and URL variable from the first view controller, but the HTML variable is only referenced in the second view controller. Once you're ready to show the HTML in the second controller, it has already been released, since the app delegate is not holding on to it.
Try changing the property declarations in the app delegate to strong:
#property (strong, nonatomic) NSString *crntURL;
#property (strong, nonatomic) NSString *crntTitle;
#property (strong, nonatomic) NSString *crntHTML;

NSDictionary returning null value for key

Im having trouble understanding why the following code displays "The First Key = (null)" in the console/terminal:
Here is the Interface:
#import <UIKit/UIKit.h>
#interface TestingViewController : UIViewController
#property (nonatomic, strong) NSMutableArray *namesArray;
#property (nonatomic, strong) NSDictionary *myDictionary;
#end
This is the implementation:
#import "DictionaryTestViewController.h"
#implementation DictionaryTestViewController
#synthesize namesArray;
#synthesize myDictionary;
- (void)viewDidLoad
{
[super viewDidLoad];
[self.myDictionary initWithObjectsAndKeys:#"value1", #"key1", #"value2", #"key2", nil];
NSLog(#"The First Key = %#", [self.myDictionary objectForKey:#"key1"]);
}
#end
Thanks in advance!
You haven't allocated your dictionary yet. It's nil at the moment, and sending message to nil does nothing.
Change it to this instead if you're using ARC
self.myDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:#"value1", #"key1", #"value2", #"key2", nil];
or this if not
self.myDictionary = [[[NSDictionary alloc] initWithObjectsAndKeys:#"value1", #"key1", #"value2", #"key2", nil] autorelease];

Share NSArray Contents between multiple methods in a single class

What am I doing wrong? My code crashes when I try to log the array. Here is my class:
#interface ArrayTestAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
NSArray *array;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) NSArray *array;
-(IBAction)buttonPressed;
#end
#implementation ArrayTestAppDelegate
#synthesize window, array;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
array = [NSArray arrayWithObjects:#"Banana", #"Apple", #"Orange", #"Pear", #"Plum", nil];
[window makeKeyAndVisible];
}
-(IBAction)buttonPressed {
NSLog(#"%#", array);
}
- (void)dealloc {
[window release];
[array release];
[super dealloc];
}
#end
This is a common memory management error in Cocoa. The arrayWithObjects method of the NSArray class returns an autoreleased object. By the time you try to log the array in the buttonPressed method, the array has already been released and you get a crash. The fix is easy:
array = [[NSArray alloc] initWithObjects:#"Banana", #"Plum", nil];
Or:
array = [[NSArray arrayWithObjects:#"Banana", #"Plum", nil] retain];
I guess the first one is better, the retain on the end of the second example is easy to miss. I would suggest that you read some more on memory management in Cocoa.