NSMutableOrderedSet causes app crash - objective-c

I have a NSMutableOrderedSet which looks like this:
self.tableViewData = [[NSMutableOrderedSet alloc ]initWithObjects:
#"Red",
#"Blue",
#"Yellow", nil];
I'm using delegate to pass data to AppDelegate:
-(IBAction)add
{
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
[delegate setData:self.tableViewData];
}
Here is AppDelegate.h:
#property (nonatomic, strong) NSMutableOrderedSet *data;
and AppDelegate.m:
#synthesize data = _data;
The problem is that the app crashes on this line:
[delegate setData:self.tableViewData];
with no error message in lldb. What is wrong here?

It looks like you are typecasting [UIApplication sharedApplication] to (AppDelegate *).
Try
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

Related

Is it possible to get a NSArray from AppDelegate?

Is it possible to get a NSArray from my AppDelegate? I need to send a array to other classes. And that array is generated in my AppDelegate. Thanks!
First of all you should have to alloc and init
In AppDelegate.h file
#property(nonatomic,retain)NSArray *books;
In AppDelegate.m file your array, then You can add objects in it.
_books = [[NSArray alloc]initWithObjects:#"test",#"test", nil];
You should have to create AppDelegate instance in your BooksDetailViewController like this,
in .h file
AppDelegate *appDelegate;
and in .m file
appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
Now you can access your array like this,
NSLog(#"Test Log :%#",appDelegate.books);
Output :
2016-07-14 13:04:08.211 Gridz[2490:39240] Test Log :(
test,
test
)
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
Now you can use any property or method like:
[appDelegate myProperty] or [appDelegate myMethod]
Hope this helps
It is possible to get the NSArray from AppDelegate to other classes.
AppDelegate.h
#import <UIKit/UIKit.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate> {
}
#property (nonatomic, strong) UIWindow *window;
#property (nonatomic, strong) ViewController *viewController; //For Xib
#property (nonatomic, strong) NSArray *arrayObjects;
#end
AppDelegate.m
#import "AppDelegate.h"
#import "ViewController.h"
#implementation AppDelegate
#synthesize arrayObjects;
As I use Xib, I set the root view controller in below method.If you use stroy board, it is enough to add NSArray objects only.Don't need to set the root view controller.
//For XIB
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
arrayObjects = [[NSArray alloc]initWithObjects:#"Steve",#"jobs",#"Tim",#"Cook",nil];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
self.window.rootViewController = navController;
[navController setNavigationBarHidden:YES];
[self.window makeKeyAndVisible];
return YES;
}
//For Storyboard
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
arrayObjects = [[NSArray alloc]initWithObjects:#"Steve",#"jobs",#"Tim",#"Cook",nil];
return YES;
}
Then in ViewController.m
You can also import the AppDelegate in ViewController.m
#import "ViewController.h"
#import "AppDelegate.h"
#interface ViewController ()
#end
#implementation ViewController
Now in viewDidLoad method
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
AppDelegate *delegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
NSLog(#"The app delegate NSArray Objects are - %#",delegate.arrayObjects);
}
The NSLog results are
The app delegate NSArray Objects are - (
Steve,
jobs,
Tim,
Cook
)

ViewController Delegate

is it possible to access a ViewController's methods from the appDelegate, like it is possible inverse with the following code:?
AppDelegate *ad = (AppDelegate *) [[UIApplication sharedApplication] delegate];
When I try
ViewController *vc = (ViewController *) [[UIApplication sharedApplication] delegate];
I get an error...
Thanks!
In your AppDelegate, assuming viewController is your rootViewController, you can get a list of all view controllers on the stack by with:
NSLog(#"List of current active view controllers:%#", self.viewController.navController.viewControllers);
To access a specific view controller in the viewControllers:
[[self.viewController.navController.viewControllers objectAtIndex:i] someMethodOfThatViewController];
ViewController *vc = (ViewController *)[UIApplication sharedApplication].keyWindow.rootViewController;
or if your delegate have properties
YourAppDelegate *ad = (YourAppDelegate*)[UIApplication sharedApplication].delegate;
ViewController *vc = ad.yourViewControllerProperty;

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;

Passing data between classes is not working

I'm trying to pass NSDictionary between classes. In my AppDelegate I have instance NSDictionary.
#interface AppDelegate : UIResponder <UIApplicationDelegate, FBSessionDelegate, FBRequestDelegate>
{
NSDictionary *contactsFromFacebook;
}
#property (strong, nonatomic) NSDictionary *contactsFromFacebook;
In my AppDelegate.m file I synthesized it as #synthesize contactsFromFacebook = _contactsFromFacebook;. Next my step (filling dictionary):
-(void)request:(FBRequest *)request didLoad:(id)result {
_contactsFromFacebook = [[NSDictionary alloc]initWithDictionary:result];
}
In my someClass.m file I want to use data from contactsFromFacebook dictionary.
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSDictionary *someNewDictionary = [[NSDictionary alloc] initWithDictionary:appDelegate.contactsFromFacebook];
But my someNewDictionary is ampty. What I'm doing wrong?
In appDelegate write a method:
-(NSDictionary*)getSomething { return self.contactsFromFacebook; }
And then in other class:
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSDictionary *someNewDictionary = [[NSDictionary alloc] initWithDictionary:[appDelegate getSomething]];
And this works fine for me.
Edit:
#Abizern comment i think resolve your issue. He is right.
"#synthesize contactsFromFacebook = _contactsFromFacebook;"
Where is _contactsFromFacebook?
All I see are the following declarations:-
NSDictionary *contactsFromFacebook;
and
#property (strong, nonatomic) NSDictionary *contactsFromFacebook;
I see no link between the strong property contactsFromFacebook and the variable _contactsFromFacebook you assign to point at the NSDictionary you instantiate

how to call drawrect method from another class when it is made in appdelegate class

I have made a method in appdelegate class which is-
#implementation UINavigationBar (category)
- (void)drawRect:(CGRect)rect{
UIImage *img = [UIImage newImageFromResource:#"Img.png"];
[img drawInRect:rect];
[img release];
}
#end
I want to set the size(x,y,width,height) of the image(Img.png) programitcally in some other class..so how to call/use (- (void)drawRect:(CGRect)rect) method in some other class?
do like this
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate drawRect:CGRectMake(x,y,width,height)];