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.
Related
I have some forms for the authentications and signup views and I want that all UITextField inside those forms have a UIButton as an accessory view, just above the keyboard. I want to have the possibility to set the title and the action for this button
Because I want all those text field have one and each will have a title and an action, and to avoid redundancy, I thought about a protocol.
I want something like extending a custom protocol, for example UITextFieldAccessoryViewDelegate and to be conform to some functions like :
-buttonAccessoryView title ... -> String
-didClickOnAccessoryViewButton.. -> ()
My mind is closed. Someone can give me some ideas to do what I want ?
You could use associated objects to solve this problem. This lets you add a property and its synthesized getter/setters.
#interface UITextField(AccessoryButton)
#property(readwrite, strong, nonatomic) UIButton *accessoryButton;
#end
#import<objc/runtime.h>
#implementation UITextField(AccessoryButton)
-(UIButton*) accessoryButton
{
objc_getAssociatedObject(self, #selector(accessoryButton));
}
-(void) setAccessoryButton:(UIButton *)accessoryButton
{
objc_setAssociatedObject(self, #selector(accessoryButton), accessoryButton, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
Include this category into your forms that need the UIButton for the text fields. Then assign action and title to a UIButton like how you normally do.
Considering everything you want to do I think you are better off using a subclass of UITextField rather than an extension.
Extensions can't add instance variables to the objects they extend, but subclasses can. As lead_the_zeppelin points out in his answer, you can use associated objects to simulate adding instance variables with an extension but it seems like you're making it needlessly complicated when a subclass gives you everything you want.
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.
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.
I've got a handful of UIViews subclasses as a part of my interface and I'm looking for an easy human readable way to differentiate them in the code -- like the label you set in the "Document" section of the UI editor.
I believe the "Accessibility Label" is exposed, but that doesn't seem like the correct use of that variable.
Am I stuck documenting which Object ID each object has or is there a more intelligible way?
There are lots of ways to do what you want to be done. Here are several of them:
#properties
The first thing that came to my mind are properties. Use your view controller as a storage class by adding following property declarations in your header file:
#property (nonatomic, weak) IBOutlet UIView *myFantasticView;
#property (nonatomic, weak) IBOutlet UIView *myGorgeousView;
...
Then, just simply connect your views to specific outlets in Interface Builder.
The only drawback is that you will have to declare a lot of properties which can become a little confusing.
Custom runtime attributes (another use of #properties)
If you're using UIView's subclasses (I assume you do), you can use your UIView subclass and declare an "identifier" property:
#interface MyView : UIView
#property (nonatomic, strong) NSString *myViewID;
...
#end
Then, assign this value using code (simple property setting) or in Interface Builder:
Now you can identify your views using one of those method. But remember that you can come up with a better, more suitable solution! :)
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