Passing data between classes using Objective-C - ios

I need some info about how to pass data between classes.. To be specific, I want to store in a class in an array some info, (using model store class), and then use it in another class..

You can do like:
For example: you want to pass Array from FirstViewController to SecondViewController.
Create Array in SecondViewController first and define it as property as in SecondViewController.h:
NSMutableArray *secondArr;
#property (nonatomic, retain) NSMutableArray *secondArr;
In SecondViewController.m:
#synthesize secondArr;
Then, for example, you want to pass Array when a button in FirstViewController is touched.
In its action (create IBAction, link it with the button's touchesUpInside), you can set it to get the instance of your second view controller, for example:
secondViewController.secondArr = firstArr;

I've posted some alternatives to the delegate pattern in Q&A What are alternatives to “delegates” for passing data between controllers?.

just declare array(let array2) in second class(MYSecondView) and do not forget to set his propert and synthesize.
and then go to first class in .h file and import class(#import "MySecondView") where you define array2.
create an object of second class(MySecondView *objMySecondView=[MySecondView alloc]init];) in your first class.
then pass value to array2 from array of first class.
like
objMySecondView.array2 setObjectFromArray=array1;

If you don't know how to do that, it's seems that you're at the very beginning of learning Objective-c and OO programming. So you better have some time to read about it
A good place to start is here

Related

Objective C: Access Variable From View Controller To NSObject

I am started learning objective c again, and I am trying to access a variable from my main view controller in my NSObject class.
How would I do that?
For example I have declared
UITextField *name;
and I want to use it in my NSObject.
The best practise would be implement delegate pattern here. Suppose you want to change the value/content of UITextField, then fire the delegate with the value. And in ViewController class, set the delegate and implement that delegate method. In that delegate method, update value/content of UITextField.
One more thing, Please make sure to update UITextField's content/value in main thread. UI related changes should be always done in main thread.
You can refer to the NSObject class via a method with the plus sign '+' +(type)anyMethod; to get the variable. If I correctly understood what you mean

Nonatomic strong / copy?

I'm building an app whereas I have a ViewController viewing a custom object, lets call this object "CustomObject". Upon a button press, a segue is triggered and hence prepareForSegue is called where I get the destination ViewController and pass self.myObject. The destination ViewController may change a few parts of the CustomObject, but those changes should not be reflected in the original ViewController if the user decides to go back to the original ViewController. The changes should only be reflected if the user pressed "Save" in the destination ViewController and hence triggering an NSNotification with a version of the CustomObject that should be reloaded in the original ViewController like so:
self.myObject = (CustomObject *)notification.object;
So my question is as follows: Which of these should I use (or any other that would be correct) - and why?
#property (nonatomic, strong) CustomObject *myObject;
#property (nonatomic, copy) CustomObject *myObject;
Thanks!
Update:
header file:
#interface CustomObject : NSObject <NSCopying>
implementation file:
- (id)copyWithZone:(NSZone *)zone
{
id copy = [[[self class] alloc] init];
if (copy)
{
// Copy NSObject subclasses
[copy setRegisterDate:[self.registerDate copyWithZone:zone]];
}
return copy;
}
You should use strong but (in prepareForSegue) create and pass a copy (or simply a different object, but in any case, don't pass the original object).
This is the opposite of the situation for which the copy property attribute was designed. With the copy property attribute, the recipient wants to ensure that the object is not mutated later behind his back: e.g., I accept an NSString but the caller passes me an NSMutableString and retains it as well, so that my string can now be changed behind my back. By calling copy, I turn the NSMutableString into an NSString, which is immutable.
Your situation, as I said, is just the opposite. Your first view controller wants to pass an object without any risk of affecting his own object. Therefore, it is up to your first view controller to make a new object and pass it, rather than passing a pointer to his own sacred object. It is not your second view controller's job to know that your first view controller needs protecting; it is up to your first view controller to protect himself.
I feel you can go for copy. Since it can be used when the object is mutable. Use this if you need the value of the object as it is at this moment. You don't want that value to reflect any changes made by other owners of the object. You will need to release the object when you are finished with it because you are retaining the copy.
Pl. refer to the below link also which gives good insight when to use which property.
Objective-C declared #property attributes (nonatomic, copy, strong, weak)
You should use "copy", because "copy" creates a duplicate instance of that object, and the new object is independent of the original object. "strong" adds a "link" to the object, it's only one object.

iOS Which is better design comparing passing the whole class to view or setting piece by piece

I have a User class has some properties such as name, email, location. And I have another class
called Post which has some properties such as title, contentand poster that is a instance of User.
There is a ViewController, inside the view controller there is a PostDetailView which is used to show post details. Now the view controller has a post object and I need to pass some values to PostDetailView. I have two options:
Pass the whole post object through initializer, which means PostDetailView has a method -initWithFrame:post. Once the view get the post object, it can get every data inside the post.
PostDetailView has some setter method such as setTitle:, setContent, setPosterName, etc. Initializer only initialize frame of view, and then using setters to pass value.
Option 1 can save lots of work in view controller but may increase coupling. Option 2 has better structure (I thought), but need additional work in both view and view controller. Therefore, my question is which one is better in terms of architecture?
Passing a model object to the view does increase the coupling unnecessarily. Setting the individual fields is better, because the binding logic is in the controller.
A third option is to build a class that contains only the data needed by the view, and pass an object of this class to the view, instead of passing the entire Post:
#interface PostViewData : NSObject
#property (nonatomic, copy) NSString *title;
#property (nonatomic, copy) NSString *content;
#property (nonatomic, readonly) MyUser *poster;
#end
Although the controller is still required to house a view-specific logic, the view remains insulated from the model, and the code becomes explicit about the content of the view-specific data.
In favor of good design and architecture it make sense to type a little more and have views decoupled from model. One technic that I've used to is to design view with properties of primitive types (String, Number etc.) and create a category for the view that has a method to configure itself with a model object of a particular type.
You can read more about this here: http://www.objc.io/issue-1/table-views.html
They talk about table view but approach can be used for any view and model with mediating controller.

Initialize object in other class

i want to ask this question to clarify my knowledge.
I have an XML file, which have elements like - name, description, latitude, longitude etc. I decide to make custom class PlaceHolder, with properties like : #property (nonatomic, strong) NSString *name; #property (nonatomic, strong) NSString *description; and other.
What i want is, to add object of that class to other. How should i init this right? And may i add it like a property to other class?
At now, in any function i need to use that class i do following:
PlaceHolder *place = [[PlaceHolder alloc]init];
place.name = #"";
place.description = #"";
Its not very convenient to init this every time, is there any way to add PlaceHolder class like property to other class?
It's not really clear what you are asking. yes, you can add a PlaceHolder property to a class. Then, you can add code that creates a PlaceHolder object where appropriate.
If the class you're creating always needs a PlaceHolder object then you can write a custom init method that creates one and installs it in the property.
If it's a view controller and only needs a PlaceHolder when the view is displayed, you could add code to your viewDidLoad that creates a PlaceHolder and installs it in the property.
A third approach would be to write a custom getter for your property and "lazy load" the PlaceHolder object the first time you reference it.
You need to provide more information if you want better guidance than that.

Changing value of an object from a different class

I have a ViewController.m with a UIButton and a UIWebView on it.
I've subclassed UIWebView to a class that is now called MyWebView.m.
What is the most efficient way to change the UIButton outlet location value from a method that is inside MyWebView.m
I thought about NSUserDefaults but it feels to me like it's the worst way to go.
Another thought was to copy the next line and also add it inside MyWebView.h:
#property (weak, nonatomic) IBOutlet UIButton *myButton;
and connect it to the button from ViewController.m but I'm also not sure if that's a right thing to do.
What does the button title represent, conceptually? Decide that, and expose it as a string property of your web view and then have your view controller observe the property with key value observing. Or alternatively, extend UIWebViewDelegate with your own protocol, and have the view controller set itself as the web view's delegate. Then have the web view notify its delegate that this value changed.
You can use the app delegate class for persisting the data through the application but this is also not recommended by the good programmers.
One other way is to use Singleton class . This creates only one object per application session so you can use the the value throughout the application also you can modify and access the value. This is the pure approach to go .You can take a look at http://www.galloway.me.uk/tutorials/singleton-classes/

Resources