with MBaas services getting really affordable, and easy to use, I was wondering if anyone could give me an advice on the following design choice ?
Context: Send the content of an NSDictionary for remote storage. So the idea is to build a key/value relation, on the fly.
How:
using the piece of code here, it is possible to retrieve the name of an instance variable. so, the key/value relation results from [{ivar_name ="the value I'm interested in from this ivar"}, etc.... ]
I understand the limitations of the proposed code, but I think they are outweighed by the benefits.
In my case, the dictionary will not live beyond the class life-cycle, so I should not keep strong references on ivars, when the View is removed from the stack. Furthermore, it's going to be NSString taken from TextFields.
However, there is one question I can't really answer: if the ivars I'm looking at are part of reusable UITableViewCells (ex: IBOutlet textField in a UItableviewCell), should I make a copy of the textField.text or can I keep a reference on the string pointed at by textField.text? or it doesn't matter?
Thanks !
Related
I have a CustomObject(of type NSObject) having an NSMutableArray property. This property contains NSDictionary objects. I need a deep copy of just the property to allow for editing in a different view controller; after editing, I desire to replace the original property with the edited deep copied property.
My question is:
Do I need to make a deep 'copyWithZone' ?
and if so, how do I implement it considering that it's just the single property that requires deep copying?
I've for now circumvented this by doing:
NSMutableArray *deepCopyArray = [NSMutableArray arrayWithArray:[NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:<CustomObject>instance.<propertyToDeepCopy>]]];
Although this works as NSMutableArray & NSDictionary implement NSCoding, it doesn't feel the right way, or is it? Kindly help :)
It's an acceptable way with multiple merits:
It works
It's simple and obvious
It's very little code
It's self contained and thus easy to change in future
Any alternative would mean you iterating over the contents and manually copying everything yourself, there are a couple of reasons you might do that:
You know what is truly immutable and you can avoid copying
You need mutable containers (yhe dictionaries in the array
Though even in some of these cases you'd want to run a similar archive based process just using a property list instead (so you continue to write minimal code and leverage supplied SDKs).
Is it recommended to add properties in categories to an Objective-C class? Is there an official Apple link?
First of all I want to say that Peter Segerblom's answer is not correct. But maybe Daji-Djan's comment is misleading.
From the very beginning:
A declared-property is solely a declaration of two (one – for readonly properties) methods. Period.
This means that it is a declaration.
This means that it refers to methods.
Therefore you can add declared-properties in a category.
But if the property is explicitly or implicitly (Apple: automatically) synthesized, it will synthesize an ivar, if there is none. This is impossible, because it would change the memory footprint of instance objects and a point in time, instance objects are already allocated.
So you have to do one of the things below:
Already having an ivar. (What makes it a bit meaningless.)
No synthesization of the declared-property.
However, this can be useful for computed properties, for properties, whose values are stored in another object, for properties, whose values are stored as associated object, for …
You can do this with associated objects. Although this is not recommended. This link has everything you need to know.
http://nshipster.com/associated-objects/
Section out of the blog:
Associated objects should be seen as a method of last resort, rather than a solution in search of a problem (and really, categories themselves really shouldn't be at the top of the toolchain to begin with).
You can easily do that -- if apple does this, I don't know. They often expose properties in categories though..
anyway, if it makes sense for your design, go ahead! Remember though that while you can add properties, you can't add variables to existing classes.
so either have computed properties, that are a kind of 'convenience wrapper' around existing functionality OR add variables using associated storage
You can't add properties to categories. I think this has something to do with the way memory is handled. Adding instance variables to a already existing object would change the size of the object.
I am creating a set of API and some users have suggested that I use id type for a particular method that can accept custom object (defined by the API) or string instead of creating two versions. Is the use of id type in method a good or acceptable practice? Does Apple do it with their any of their API?
That would be very poor practice. If you're creating an API you need to retain full control, and allowing users to pass any object to your method at which point you would have to cast it to that object or string you mentioned could be fatal depending on what's passed. Creating two methods with different parameters is not only okay, but follows the tenets of polymorphism to the T.
Accepting id is not in itself good or bad practice. How much manual procedural if/then/else/if/then/else nonsense will you acquire? If quite a lot then something is wrong.
Put another way: if the conditional logic related to different kinds of object ends up being implicit, via the Objective-C dispatch mechanisms, then the design is good. If you end up impliedly reimplementing dynamic dispatch then you've gone completely wrong.
Apple does it frequently. Just off the top of my head there are:
as per Nikolai's comment, all the collection types: set, dictionary, array, etc.
anything that takes %# as a format specifier: NSLog, certain methods on NSString, etc.
anything that still uses an informal protocol.
anything in or semi-close to the runtime like key-value coding.
archiving and the user defaults.
anywhere that storage is offered for your own use — the hardy userInfo on NSTimer and the rest.
anywhere that target/action is used — all UIControls, the notification centre, etc.
As per my comment, suppose your custom class had this method:
- (NSData *)dataUsingEncoding:(NSStringEncoding)encoding
And suppose it were the only method being called by whomever is being passed either a string or your custom object. Then id would be the right choice, since you'd have in effect implemented an informal protocol, and the thing being passed an object genuinely doesn't care whether it's a string or not. The only contractual requirement is the informal protocol and the protocol is informal i.e. has no footprint on the type syntax.
Conversely, suppose your custom class had no methods in common with NSString and your code just looked like:
- (void)myMethod:(id)object
{
if([object isKindOfClass:[NSString class]])
[self myMethodOnString:object];
else
[self myMethodOnCustomClass:object];
}
Then id would be inappropriate. You're just obscuring what the method does and implicitly reproducing work that's built into the runtime anyway.
I am a new learner of iOS and I am reading "iOS Programming 4th Edition-Big Nerd Ranch",there is a question while I am reading the 7th chapter.
it says
A button’s life is relatively simple. For objects with more complex lives, like a text field, Apple uses the delegation pattern. You introduce the text field to one of your objects: “This is your delegate, when anything interesting happens in your life, send a message to him.” The text field keeps a pointer to its delegate. Many of the message it sends to its delegates are informative: “OK, I am done editing!”.
It makes me confused,because at first,it means that the text field can be introduced to one of my objects as a delegate of them,but finally it says " the text field keeps a pointer to its delegate ". Isn't the text field itself a delegate of others,is it? So I don't understand who is whose delegate ? Does it mean that the text field can be delegate of others,but it can also have delegate of itself? or else?
Thanks in advance!
Your object is the delegate. The text field will be sending the messages to it.
Understand what delegate means: It's your delegate -- acting on behalf of your program logic, and interacting with the UI object to tell it what you want done. In a sense ambassador would be a better title, since it's representing you in some "remote" location.
Just as there might be a US ambassador to Thailand, your program might have an ambassador to the UITextField object. When you create the UITextField you tell it what object is it's ambassador/delegate and then the UITextField talks to that object when it needs to know what you want to do.
Many of Apple's framework objects take a delegate. A delegate is a pointer to some anonymous object that you know very little about. All you know about it is that it understands a certain set of calls (a protocol). It's like a private lingo.
The idea is that the system object sends information to the delegate to either tell it about what has happened (the user selected the picker item at index 4) or ask it about how it should behave (The user wants to scroll to the left. Should I allow it?)
By using the delegate design pattern, you can build general-purpose objects that can be used in a wide variety of situations, by a wide variety of different objects.
When you read delegate, think "customer". A system object is a shopkeeper. Its delegate is a customer.
The shopkeeper doesn't need to know much about his customer. He takes an order for a product, calls out the customer's number when the order is ready, hands over the product, takes some money, and moves on. The customer doesn't even have to speak very much of the shopkeeper's language - only enough to place the order, understand when the order is ready, and how to pay for it.
The protocol is the language that the object (shopkeeper) uses to talk to it's delegate (customer). It's a limited, formally defined language. Any delegate (customer) who understands the required words in the object's (shopkeeper's) language (protocol) can get services from the object (shopkeeper).
BTW, you should accept the answer that helped you first and/or best, and up-vote all answers that you find useful. In this case I think you should accept #MirekE's answer. He was the first one to give you a clear answer.
I have been looking at Swift the last couple of days and it looks good, I am confused on a point though even after review of the guide Apple published.
I understand that memory management in Swift uses ARC and therefore quite safe, however in situations where I'd like more fine grained control of object creation and destruction I'm slightly confused.
Take these two simple examples:
In ObjC, when you'd (for example) like a UIViewController you intend to push to stay around for the lifetime of your app and only be created once (say because it's expensive to create), you'd make it a property and then wrap it's Alloc Init like this:
if (!self.myProperty)
{
self.myProperty = [[MyObj alloc] init];
}
This way it only creates once, keeps state and the same object instance can be reused indefinitely, yielding known object references, and good performance not having to recreate each time the viewController goes out of scope.
Another example of this is with NSMutableString, vs Swifts String.
You can set an NSMutableString's string many times and it will keep the same object reference, however this doesn't seem to be the case with a Swift String when changing it.
This may just be 'deprecated thinking in Objective C' but is there a best practice with regard to keeping around expensive objects or to keep state (same object) for certain objects during the lifetime of their usage.
I think what you're looking for is a "Lazy stored property":
The example in the swift docs is:
class DataManager {
#lazy var importer = DataImporter()
var data = String[]()
// the DataManager class would provide data management functionality here
}
and it says about #lazy:
A lazy stored property is a property whose initial value is not calculated until the first time it is used. You indicate a lazy stored property by writing the #lazy attribute before its declaration.
The comment about NSMutableString is a little different, you can continue to use NSMutableString in your swift code, but Apple are encouraging developers to use the Swift built-in types whenever possible :)
see the "String Mutability" section in the swift docs