Updating view with a data from the method of another class - objective-c

I am trying to update my UIProgressView with some data from a method of my utility class.
Now, just because for updating my UIProgressView, i am holding that method in my view controller class and everything works fine. Because i can reach the loop in that method with a global variable so i can update my progress. But if i want to move this method to my utility class, what am i supposed to do to keep informed my UIProgressView. Thanks.

What I would suggest is to redesign your utility class to be a singleton
Here is an example of code of your utility class:
UtilityClass.h file:
#interface UtilityClass : NSObject
+ (UtilityClass *)sharedInstance;
- (CGFloat)awesomeMehod;
#end
UtilityClass.m
#implementation UtilityClass
+ (id)sharedInstance
{
static UtilityClass *_instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[UtilityClass alloc] init];
});
return _instance;
}
- (id)init
{
self = [super init];
if (!self) return nil;
// Regular initialization, however keep in mind that it will be executed just once
return self;
}
- (CGFloat)awesomeMethod
{
return 42.0f
}
#end
Now from your view controller you will call
CGFloat progress = [[UtilityClass sharedInstance] awesomeMethod];
[self.progressView setProgress:progress];
keep in mind several things:
It's one of possible approaches and I would go and read about various
design patterns that might come in handy one day
Probably a good idea to refresh knowledge on view controllers and the way they interact
For class to become a proper singleton, you also should override
methods such as alloc, init, initWithZone, dealloc, release
etc (list of methods to override will vary if you use ARC), here is
an example of doing that, although dispatch_once takes care of
#synchronize() call. For now, as long as you "instantiate" you class only
through calling sharedInstance class method you will be fine.

Related

One NSDictionary visible everywhere in application

Now I am developing an iOS application which works like this:
User scans QR code,
App searches for a specific key - > value,
it gives out a value to the user.
Currently I have two ViewControllers - the main and "value" ViewController, which is inherited from main. The problem is that if I create NSDictionary in main VC it is not visible in "value" VC. Main VC gives only the string (QR code, the key) through the segue. So, the value VC has to search for key and display the value.
What I ask is some kind of global variable or one DataSource visible across the whole app. Of course, I can implement NSDictionary initialisation inside value ViewDidLoad method and it will work, but this is not the point. New modules are to be added there and the variable has to be global. I googled a lot and got the idea that singleton pattern can be helpful here. I tried to implement it, but no idea how to do. Do I need it, or it is too complex for this kind of DataSource?
Thank you!
The basic idea is, you will still need to #include the header file of the place where this dictionary will be. The solution that Naveen proposes means that you will be including the header for the app delegate wherever you want to access it. Whether to use the app delegate for this purpose or not is kinda grayish. Some people often do this, some say its a bad use of it.
The singleton approach means that you will create a class, that will always contain the same information since the init method will return object that was previously created.
For the singleton aproach, imagine I have a database manager class. So in the header of this class (the DatabaseManagerSingleton.h) ill have this:
#interface DatabaseManager : NSObject
+ (DatabaseManager*)sharedInstance;
// Your dictionary
#property (nonatomic,strong) NSMutableDictionary* someDictionary;
The implementation will look like this: (check how "sharedInstance" initializes the object)
#implementation DatabaseManager
#pragma mark - Singleton Methods
+ (DatabaseManager*)sharedInstance {
static DatabaseManager *_sharedInstance;
if(!_sharedInstance) {
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_sharedInstance = [[super allocWithZone:nil] init];
});
}
return _sharedInstance;
}
+ (id)allocWithZone:(NSZone *)zone {
return [self sharedInstance];
}
- (id)copyWithZone:(NSZone *)zone {
return self;
}
- (id)init
{
self = [super init];
if (self != nil)
{
// Custom initialization
_someDictionary = [[NSMutableDictionary alloc] init];
}
return self;
}
Now, a VERY important thing is that, any place you want to use this object should first include the header:
EDIT: To use it in your code:
1) add the header
#import "DatabaseManager.h"
2) initialize the object
DatabaseManager *databaseManager = [DatabaseManager sharedInstance];
3) do whatever you need
// Initialize the dictionary
databaseManager.someDictionary = [[NSMutableDictionary alloc] initWithObjectsAndKeys:#"OBJECT",#"someKey", nil]; // In this case the object is just a NSString.
// Access
[databaseManager.someDictionary objectForKey:#"someKey"];
Put as a property on Appdelegate
#property (nonatomic,strong) NSDictionary * sharedData;
Access anywhere like
NSDictionary *sharedData= ((APPDelegate *) [UIApplication sharedApplication].delegate).sharedData;

Writing my own block method

I am trying to follow through examples from other as well as Apple. I'm lost.
I have a singleton class that I use to handle my user logging in (challenges a web server, etc.).
I want to create a block I can call, pass in the username/password. The block will perform the web service calls then return if it was successful or not.
This is what i've manage to get working so far:
My singleton class looks like this:
.h
typedef void (^AMLoginBlock)(NSString *userName, NSString *password);
#interface AuthManager : NSObject
+ (id)sharedManager;
+ (bool)loginUserWithBlock:(AMLoginBlock)block;
#end
.m
#implementation AuthManager
+ (id)sharedManager
{
static dispatch_once_t pred = 0;
__strong static id _sharedObject = nil;
dispatch_once(&pred, ^{
_sharedObject = [[self alloc] init]; // or some other init method
});
return _sharedObject;
}
+ (bool)loginUserWithBlock:(AMLoginBlock)block {
NSLog(#"im printing from AM");
return true;
}
#end
I then call the method like so:
bool rtn = [AuthManager loginUserWithBlock:^(NSString *userName, NSString *password) {
NSLog(#"im here in the block LVC.");
}];
My question is three parts:
How do I write a completion handler for the block similar to UIView animation... block.
Is it a good idea to perform these web service calls from a block based implementation?
Should I be declaring the block method like so:
- (bool)loginUserWithBlock:(AMLoginBlock)block;
instead of using +(bool)loginUser.. since it is in a singleton class. Not sure if this will cause multiple instances of the singleton to be created.
My goal is to be able to call this block like you call [UIView animation..]. So I can simply do:
[AuthManager loginUserWithUsername:foo
password:bar1
completion:^(BOOL finished) {
if (finished)
//push new view controller.
else
//spit out error
}];
Completion Handler
You will want to copy the completion block to a class iVar:
#property (nonatomic, copy) void (^completionHandler)(bool *);
Because you are saving the block, you need to have a non-class method take the block (see following for how to do this without violating your singleton). An example of your method could be:
- (void)loginUserWithUsername:(NSString *)username
password:(NSString *)password
completion:(void(^)(bool *finished))completionBlock
{
// Copy the blocks to use later
self.completionHandler = completionBlock;
// Run code
[self doOtherThings];
}
Then when your login code has finished its work, you can call the block - here I pass self.error, a bool to the block :
- (void)finishThingsUp
{
// We are done with all that hard work. Lets call the block!
self.completionHandler(self.error);
// Clean up the blocks
self.completionHandler = nil;
}
Good Idea
Well, this is a philosophical question, but I will say this: Blocks in Objective-C allow you to write code that performs a single task and easily integrate it into many programs. If you chose to not use a completion handler in your login code you would need your login code to:
Require that classes using it implement a protocol (as in a LoginDelegate)
Use some other system of informing your code such as Key Value observing or Notifications
Hard code it to only work with one type of calling class
Any of the above approaches are fine, I feel a block-based call back system is the simplest and most flexible. It allows you to just use your class without worrying about additional infrastructure (setting up notifications, conforming to protocols, etc. ) while still letting you reuse it in other classes or programs.
Singelton
Methods that begin with a + in Objective-C are class methods. You cannot use class methods to manipulate iVars, as who would own that data?
What you can do is have a class method that always returns the same instance of that class, allowing you to have an object that can own data, but avoid ever having more than one of them.
This excellent Stack Overflow answer has sample code.
Good Luck!

singleton in objective c

I saw a singleton example on objective-c book. However, I don't know if there is difference of meaning of 'singleton' definition between objective-c and other langs. Can this [[SingletonClass alloc] init] still be used to create a new object? If yes, how to guarantee there is only one object in the memory?
#import "SingletonClass.h"
#implementation SingletonClass
static SingletonClass *sharedInstance = nil;
// Get the shared instance and create it if necessary.
+ (SingletonClass*)sharedInstance {
if (sharedInstance == nil) {
sharedInstance = [[super allocWithZone:NULL] init];
}
return sharedInstance;
}
// We can still have a regular init method, that will get called the first time the Singleton is used.
- (id)init
{
self = [super init];
if (self) {
// Work your initialising magic here as you normally would
}
return self;
}
If you want a true singleton, i.e. an object that can be instantiated only once, take a look at Apple's documentation: Creating a Singleton Instance.
Basically, the idea is to override a number of methods related to allocating and managing objects: +allocWithZone (which is called by +alloc), -retain, -release, -copyWithZone, etc., so that it becomes quite difficult to create more than one instance of your singleton class. (It's still possible to create a second instance by calling the runtime directly, but this should be enough to get the point across.)
Pretty much every blogger who has ever written about Objective-C in any capacity has offered an opinion on how to implement singletons. Many of those opinions seem pretty good, and most of them are fairly similar. It's clear that Dave DeLong knows what he's talking about, and his piece on singletons is short, sweet, and gets straight to the point.
I don't know if there is difference of meaning of 'singleton' definition between objective-c and other langs.
It follows the common definition of languages derived from C.
Can this [[SingletonClass alloc] init] still be used to create a new object?
Yes
If yes, how to guarantee there is only one object in the memory?
Avoid enforcing the pattern (e.g. do not force it to be a singleton). Just make a normal object. Then if you really want only one instance, create an instance and save it someplace for reuse (your app delegate is one typical place for this, because it is typically created once per execution).
In practice, most (>95%) ObjC singleton implementations i've seen in the wild are used for the wrong reasons, and would have been better or as good as normal objects.
Every solution linked in the answers so far has (at minimum) subtle problems, dangers, or undesirable side-effects.
There is no language support for singletons, but you can do it by hand. Look at the singleton example here. It doesn't look like it is thread-safe, though. I would allocate the object in +initialize instead of +sharedManager.
You can create a singleton in Objective-C by doing the following:
+(MyAPI *)shared {
static dispatch_once_t queue;
static MyAPI *singleton = nil;
dispatch_once(&queue, ^{
singleton = [[MyAPI alloc] init];
});
return singleton;
}
This will also ensure that it is thread safe. Without using the dispatch_once you run the risk of multiple threads trying to access it at the same time when one is in the middle of allocating it, and the other is trying to use it.
Singleton class is used to save the data for use anywhere in app.
//SingletonObject
#define saveDataSingletonObject ((SaveDataSingleton*)[SaveDataSingleton sharedManager])
#interface SaveDataSingleton : NSObject
#property (nonatomic,strong) NSMutableArray *DataArr;
+ (id)sharedManager;
-(void)clearAllSaveData;
#end
#implementation SaveDataSingleton
#synthesize DataArr;
+ (id)sharedManager {
static SaveDataSingleton *sharedManager;
if(!sharedManager) {
#synchronized(sharedManager) {
sharedManager = [SaveDataSingleton new];
}
}
return sharedManager;
}
-(void)clearAllSaveData{
DataArr=nil;
}
- (id)init {
if (self = [super init]) {
DataArr = [[NSMutableArray alloc]init];
}
return self;
}
// using setter getter save and retrieve data
+(void)setDataArr:(NSMutableArray *)Dataarr
{
self.DataArr = [[NSMutableArray alloc]initWithArray:Dataarr];
}
+(NSMutableArray *)DataArr
{
return self.DataArr;
}
#end
Save and Retrieve data // Use singleton Object
// save data using setter function.
[saveDataSingletonObject setDataArr:Array];
//fetch data using getter function.
NSArray *arr=[saveDataSingletonObject DataArr];

Singleton or Class methods [duplicate]

This question already has answers here:
What does #synchronized() do as a singleton method in objective C?
(6 answers)
Closed 3 years ago.
After reading the responses to a question about singletons in Objective C it appears that each solution makes some tradeoff in regards to threading in the instance accessor. i.e.
#synchronized(self)
{
if (sharedInstance == nil)
sharedInstance = [[MySingleton alloc] init];
}
return sharedInstance;
This essentially single-threads access to the singleton, and if it's something that's used frequently in an operation, seems like something that could cause threads to unnecessarily contend.
What's the downside to simply using the class object as the singleton instance, and exposing functionality via class methods, i.e.
#interface MySingleton : NSObject {
}
+ (void)doSomething;
#end
#implementation MySingleton
+ (void)initialize {
//do some setup if necessary
}
+ (void)doSomething {
//do something
}
#end
In this way we avoid doing the lock + check every time we want to reference the singleton object and we can also eliminate having to store it in a local or method ivar.
This approach also lets the runtime guarantee that only one instance (the Class object) exists in the system at any given time.
EDIT
There's more here than just threading, with a traditional singleton you usually write code like this:
MySingleton *instance = [MySingleton getSharedInstance];
NSObject *someResult = [instance getResult];
//or
if (instance.someProperty) {
//do something
}
However if your singleton is a class instance, you essentially eliminate the need call getSharedInstance all the time. Consider this code:
NSObject *someResult = [MySingleton getResult];
//or
if ([MySingleton someProperty]) {
//do something
}
I hear the point that you have to store your data in file local static variables, or in global variables (yuck). But it's really not all that different from a traditional singleton with the exception that you lose Objective-C 2.0 properties (instead you have to use traditional accessor methods).
Here's one key tradeoff for me that seems like a win. In a traditional singleton you end up overriding -copyWithZone, +allocWithZone, -retain, -retainCount, -release and -autorelease if you really want to get things right.
This seems like an awful lot of work to do every time you want to write a simple Singleton object (they happen to be pretty useful). So why not simply just replace it with this:
#implementation MySingleton
+ (void)initialize {
//do your setup
}
- (id)init {
NSAssert(NO, #"You should read the documentation on singletons.");
}
#end
It's a lot lighter in terms of code, and unless your consumers are really sneaky they won't ever create two instances.
Get to the point already
My question is really this:
Is there any drawback to using the Class object as the instance of your singleton?
It seems like you can take all the same steps in terms of threadsafety, memory efficiency etc. without having to remember to override so many methods and accessors or litter your code with instance checks.
With iOS 4.0 or later, by far the best solution is to just use dispatch_once, as in
+ (id)sharedInstance {
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
sharedInstance = [[MyClass alloc] init];
});
return sharedInstance;
}
You may also want to consider using a single dispatch_queue to serialize access to the internals of a class. If all your public methods just run a block on the same dispatch_queue then you won't have to worry about concurrency issues.
This is my first post on Stack Overflow... (so prepare for stupidity)
I think there is a hybrid solution that might be useful.
I want to set and get (global) values out of a singleton class without having calling "getSharedInstance". I'd want the code to look like this...
frameRate = Singleton.frameRate;
Singleton.frameRate = 42;
To achieve this, each variable we need to store in the singleton has a getter and setter class method. The class method then goes to an instance to store the data in an ivar. The instance isn't directly accessed by the main program.
The getter looks like this:
+ (int) frameRate
{
return [[Singleton instance] ivarFrameRate];
}
The (ugly) instance call is hidden inside the class code.
By calling the instance method here, the class method will automatically instantiate an object when first used. Once the singleton is instantiated, the instance stores ivars conventionally. Here, I am prefixing with "ivar" make the ivar explicit.
#property int ivarFrameRate;
and
#synthesize ivarFrameRate;
This automatically creates conventional getter (and setter) methods to access the ivar.
(edit - here is a complete example)
// Singleton.h
#import <Foundation/Foundation.h>
#interface Singleton : NSObject
{
float ivarFrameRate
}
#property float ivarFrameRate;
- (id) init;
+ (Singleton *) instance;
+ (float) frameRate;
+ (void) setFrameRate:(float)fr;
#end
and
// Singleton.m
#import "Singleton.h"
#implementation Singleton
#synthesize ivarFrameRate;
static Singleton* gInstance = NULL;
+ (Singleton*)instance
{
#synchronized(self)
{
if (gInstance == NULL)
gInstance = [[self alloc] init];
}
return(gInstance);
}
- (id)init
{
self = [super init];
return self;
}
+ (float) frameRate
{
return [[Singleton instance] ivarFrameRate];
}
+ (void) setFrameRate:(float)fr;
{
[[Singleton instance] setIvarFrameRate:fr];
}
This is fine, but still just changes your circumstances rather than fixes your problems. Unless you don't have any actual data tied to your singleton, in which case this will work just fine. Anytime you access central data you will need to properly make it thread-safe.
Additionally, without some kind of iVar I don't know of a way to store data (that is intended) directly in a class.
In the example above I would code it in this way, getting the same result as you are proposing and only taking the performance hit if we are creating/re-creating the singleton:
if (sharedInstance)
return sharedInstance;
#synchronized(self)
{
if (sharedInstance == nil)
sharedInstance = [[MySingleton alloc] init];
}
return sharedInstance;
Keep in mind that either way, if you are accessing data that is potentially changing on different threads then you'll have to make that code thread-safe anyway, either with very careful planning or using code to ensure there are no problems. I'd recommend a mix, but when in doubt the latter when at all possible. =)
If you use a class as your singleton, the only way to store data would be to use static file variables and global variables. If you are going to go so far that you make a class you don't plan to instantiate, you might as well just use standard C functions:
void doSomething(void);
void doSomething() {
//do something
}

What's the correct method to subclass a singleton class in Objective -C?

I have created a singleton class and I want to create a class which is subclass of this singleton class, what is the correct method to do it
I don't know about Objective-C in particular, but in general singleton classes should prevent subclassing. If you've got an instance of the base class and an instance of the subclass, then you've effectively got two objects you can regard as instances of the base "singleton" class, haven't you?
As soon as you've got two instances, it's not really a singleton any more... and that's leaving aside the possibilities that there are multiple subclasses, or that the subclass itself allows multiple instances to be created.
Of course you can change your base class so it just has a way of getting at a single "default" instance, but that's not quite the same as making it a singleton.
If Jon didn't convinced you to not do it, you should do it this way:
In your superclass, init your singleton instance with [[[self class] alloc] init] so then you always get an instance of the class with which you are calling the sharedInstance method. And you don't have to overwrite the sharedInstance method in your subclass.
[SuperClass sharedInstance] //-> instance of SuperClass
[SubClass sharedInstance] //-> instance of Class
I made an example "base class" for singleton, you can check it here: https://github.com/stel/DOSingleton
Jon Skeet makes a good point about whether you’d really have a singleton if you’re allowed to instantiate both the class and its subclass. Putting that aside, here’s a pattern you can use so that so you only have to define the shared-instance getter once, in the parent class:
// this code goes in the implementation of the superclass
static Sprocket *defaultSprocket;
+ (instancetype) defaultSprocket
{
if (defaultSprocket == nil)
defaultSprocket = [[[self class] alloc] init];
return defaultSprocket;
}
This approach has the following advantages:
Using [self class] allows e.g. [SprocketSubclass defaultSprocket] to return an instance of SprocketSubclass instead of Sprocket
Using instancetype allows the compiler to type-check the result of this method: it’ll be Sprocket when you invoke it as +[Sprocket defaultSprocket] but SprocketSubclass when you invoke it as +[SprocketSubclass defaultSprocket].
Notably, you can define this accessor method in the base class and then you don’t have to do anything in the subclasses!
(Hat tips to NSHipster for explaining why instancetype is so cool and bbum for reminding me of it recently.)
If what you are looking for is a quick way to setup new singletons. This pseudo abstract singleton base class is what I use:
Reusable base class
H
#define CREATE_SHARED_INSTANCE \
+ (instancetype)sharedInstance { \
static dispatch_once_t once; \
static id instance = nil; \
dispatch_once(&once, ^{ \
instance = [[self alloc] init]; \
}); \
return instance; \
}
#interface SharedObject : NSObject
+ (instancetype)sharedInstance;
#end
M
#implementation SharedObject
+ (instancetype)sharedInstance {
[NSException raise:#"Call to unimplemented sharedInstance" format:#"%# does not implement sharedInstance.", NSStringFromClass([self class])];
return nil;
}
#end
Then each subclass
H
#import "SharedObject.h"
#interface SomeSubclass : SharedObject
#end
M
#implementation SomeSubclass
CREATE_SHARED_INSTANCE
#end
...and use like any singleton.
[[SomesSubclass SharedInstance] someMethod];
If you call the abstract base class, or forget to include CREATE_SHARED_INSTANCE in your subclass, you will get a friendly exception raised.
This way you can setup a new singletons easily at no performance hit.
The simplest way to achieve this is implement the standard singleton accessor in both the class and the subclass. This way each class behaves as a proper singleton, that is there is only ever one instance of both. If you attempt to reuse the accessor of the parent class in the subclass and then if you make use of both classes, you run the risk of the accessor returning the wrong instance because their behaviour would depend on the order of how they are accessed.
You should not use instancetype for the singleton accessor to help prevent this mistake. You'll notice Apple don't use it for their singletons e.g. UIApplication and CKContainer.
If you would like existing code that accesses the super-class's singleton method be given an instance of the subclass then likely you need to redesign, see MrJre's answer.
I had a similar problem and the way I solved it is to create a singleton wrapper class which has all the extra functionality. This singleton class contains the original singleton (has the singleton instance as a member variable). This way you can avoid dirty tricks.
I had a similar problem, I had multiple targets that needed to have a slightly different singleton implementations: each target would include the base class + a specific subclass. This was achieved by writing the base class like so:
+ (SingletonBaseClass*) sharedInstance {
static SingletonBaseClass * sharedInstance = nil;
if (!sharedInstance) {
sharedInstance = [[[self class] alloc] init];
[sharedInstance customInit];
}
return sharedInstance;
}
The key difference is [self class] instead of the actual class name. That way when the we call: [SingletonSubclass sharedInstance] the correct object is instantiated.
Please note that this is a specific case, in the general case I agree with previous answers.
I had the same problem. This is how to solve: You need to use a static dictionary to subclass a singleton. For exemple:
Class A : NSObject -> Singleton
Class B : A
Class C : A
#implementation A
// Dictionary that holds all instances of API subclasses
static NSMutableDictionary *_sharedInstances = nil;
+ (instancetype)sharedInstance
{
id sharedInstance = nil;
#synchronized(self)
{
NSString *instanceClass = NSStringFromClass(self);
if (_sharedInstances == nil)
_sharedInstances = [NSMutableDictionary dictionary];
// Looking for existing instance
sharedInstance = [_sharedInstances objectForKey:instanceClass];
// If there's no instance – create one and add it to the dictionary
if (sharedInstance == nil)
{
sharedInstance = [[super allocWithZone:nil] init];
[_sharedInstances setObject:sharedInstance forKey:instanceClass];
}
}
return sharedInstance;
}
Now you can use [B sharedInstance] and [C sharedInstance] without problems!