patternMinor
Storing global constants in app delegate or singleton
Viewed 0 times
globalappdelegatesingletonstoringconstants
Problem
I am converting a non ARC projecs to ARC. I just found that after login in my old app, the data is stored in app delegate objects, like
I am bit confused at it, because my app delegate is looking like constant class and
Old app Delegates.h:
and in similar allocation of array in didfinish launch.
I did same things and code is working but is it the right way of using objects in app delegate.
Please suggest how I should opt a singleton-based approach to declare, alloc and store various objects for various view controllers or something else.
Home_DataArray, various flags and some other objects.I am bit confused at it, because my app delegate is looking like constant class and
BoolDidFinishLaunch looks like parent of various code. Old app Delegates.h:
@property (nonatomic, copy) void(^backgroundTransferCompletionHandler)();
@property(nonatomic)BOOL activatedFromBackground;
@property(nonatomic,strong)IBOutlet UIViewController *SplashViewController;
@property(nonatomic,strong)IBOutlet UIViewController *AppCodeViewController;
@property(nonatomic,strong)IBOutlet UINavigationController *navControl;
@property(nonatomic,strong)NSMutableArray *arrHomeProducts;
@property(nonatomic,strong)NSMutableArray *arrayDownloadProducts;
@property(nonatomic,strong)NSString *AppNIB;
@property(nonatomic,strong)NSBundle* languageBundle;
@property(nonatomic,strong)UIViewController* loginVC;
@property(nonatomic,assign)BOOL acceptedMessage_Status;
@property(nonatomic,strong)NSIndexPath *selectedWebsiteIndex;
@property(nonatomic,strong)NSString *selectedWebsiteID;
@property(nonatomic,strong)NSString *userID;
@property(nonatomic,strong)NSString *partID;
@property(nonatomic,strong)NSString *websiteID;
@property(nonatomic,strong)NSString *BrandName;
@property(nonatomic,strong)NSString *driverSide;
@property(nonatomic,strong)NSString *str_bundle;
@property(nonatomic,strong)NSString *str_BundleCost;
@property(nonatomic,assign)BOOL isCalledFromSafariBrowser;
-----------------------------------------------------------
------------------------------so on ---------------------------and in similar allocation of array in didfinish launch.
I did same things and code is working but is it the right way of using objects in app delegate.
Please suggest how I should opt a singleton-based approach to declare, alloc and store various objects for various view controllers or something else.
Solution
Storing everything in a global singleton can be problematic, I wouldn't recommend that.
I worked on a project once where all data ever passed to view controllers from outside was stored a giant singleton class with a lot of properties. Essentially these properties were just global variables.
All this led to bugs where some view controller changed a variable at a wrong point in time and another view controller didn't expect that. If you ask anybody on the internet, they are probably going to say that singletons are bad. And in most situations they are, especially like this one.
So instead of using a singleton I would recommend passing parameters to view controllers somehow before you show them. It can be a as simple as setting a property:
If
I think this is called property injection (a kind of dependency injection). There is also constructor (initializer) injection:
There is also a great article on objc.io about this stuff.
I worked on a project once where all data ever passed to view controllers from outside was stored a giant singleton class with a lot of properties. Essentially these properties were just global variables.
All this led to bugs where some view controller changed a variable at a wrong point in time and another view controller didn't expect that. If you ask anybody on the internet, they are probably going to say that singletons are bad. And in most situations they are, especially like this one.
So instead of using a singleton I would recommend passing parameters to view controllers somehow before you show them. It can be a as simple as setting a property:
@interface ViewController : UIViewController
@property (nonatomic) NSString *someParameter;
@end
@implementation ViewController
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// Update your UI based on someParameter. For example:
self.myAwesomeLabel.text = someParameter;
}
@endIf
ViewController presents another view controller that happens to need someParameter too, what previously used to be a simple access to your singleton property now has to be replaced with code that will explicitly pass someParameter to the presented view controller like so:AnotherViewController *vc = [[AnotherViewController alloc] init];
vc.someProperty = self.someProperty;
vc.anotherProperty = @"Another property";
[self presentViewController:vc animated:YES completion:nil];I think this is called property injection (a kind of dependency injection). There is also constructor (initializer) injection:
@interface ViewController : UIViewController
@property (nonatomic, readonly) NSString *someProperty;
- (instancetype)initWithSomeProperty:(NSString *)someProperty;
@end
@implementation ViewController
- (instancetype)initWithSomeProperty:(NSString *)someProperty {
if (self = [super initWithNibName:nil bundle:nil]) {
_someProperty = someProperty;
}
return self;
}
@endThere is also a great article on objc.io about this stuff.
Code Snippets
@interface ViewController : UIViewController
@property (nonatomic) NSString *someParameter;
@end
@implementation ViewController
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// Update your UI based on someParameter. For example:
self.myAwesomeLabel.text = someParameter;
}
@endAnotherViewController *vc = [[AnotherViewController alloc] init];
vc.someProperty = self.someProperty;
vc.anotherProperty = @"Another property";
[self presentViewController:vc animated:YES completion:nil];@interface ViewController : UIViewController
@property (nonatomic, readonly) NSString *someProperty;
- (instancetype)initWithSomeProperty:(NSString *)someProperty;
@end
@implementation ViewController
- (instancetype)initWithSomeProperty:(NSString *)someProperty {
if (self = [super initWithNibName:nil bundle:nil]) {
_someProperty = someProperty;
}
return self;
}
@endContext
StackExchange Code Review Q#141878, answer score: 4
Revisions (0)
No revisions yet.