As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I am used to functional programming. Now writing for iOS I find myself using class methods (+) frequently, rather than creating instances (from -).
Usually I use class methods for small, recurring tasks - like sending async requests, updating database, storing/retrieving preferences etc.
Is this the right thing to do, or should I try to change my thinking more and start using instances instead? Is it even possible to avoid using class methods all together?
My best recommendation would be to look at how Foundation and Cocoa is doing and do it similarly. There is a place for class methods in Objective-C.
Some examples of class methods include
[UIView animateWithDuration:0.3 animations:^{
// Animation here...
}];
and
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *date, NSError *error) {
// Handle response here ...
}];
There is a third alternative supported by Objective C for encapsulating functionality that does not need implicit access to instance variables - it is using "plain" C functions. Unlike class functions, "plain" C functions do not use virtual dispatch, which may be important in vary tight loops.
Note that class methods provide more functionality than, say, static methods of Java, C++, and C#: they support overriding, letting class method in base classes use more specific implementations in derived classes.
Class methods are used when you do not need any instance of the class, and your purpose gets served only by a method call of that like [[NSUserDefaults standardUserDefaults] synchronize];
In MRC
The alloc/init combination gives you an owning reference. That means you must release it later on. The classMethod returns a non-owning reference. You may not release it.
i.e.,
Person *firstPerson=[Person personWithName:#"AnoopVaidya" address:#"India"];
In ARC, for the above there is not such differnce.
Related
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I am an average iOS developer. The first design pattern that I saw heavily being used was Delegation pattern which was mostly being used for callback functionality.
Now that blocks are there in Objective C and I am seeing more and more libraries heavily using them and avoiding delegates, I am wondering, are blocks permanent replacement for delegate pattern using protocols ?
I recently used MKNetworkKit in a project, I created a wrapper class on top of it, the library is block based so all my code that would encapsulate a call to one of there block based code turned ot to be another block based code.
I found that it was very convenient initially, but was difficult to debug and modify as the code looked complex (callback inside callback inside callback!)
Any tips on when to use what and certain best practices ?
Delegates and blocks are both used for something to "call back" the result, usually to the thing that created it. There are some differences:
Using a delegate protocol, the method names you must implement to receive the callback are fixed. That means, if you need to receive callbacks from multiple possible actions using the same delegate protocol, you must somehow distinguish them. With blocks, there are no fixed names; you simply pass a block object with a particular signature. You can pass different block objects to different actions.
Delegate protocols often (but not always) contain more than one callback method, e.g. a "success" and a "failure" callback. Each block can only serve as one callback. Many libraries try to "combine" multiple delegate callbacks into a single block callback, by using multiple arguments, e.g. the block has two arguments (result, error), where if "error" is nil it corresponds to the original "success" callback, with "result" being the data; and if "error" is not nil, it corresponds to the original "failure" callback. Another option would be to give multiple blocks separately to the action (e.g. it has a "success block" property, and "failure block" property, which you can set). This is more general, and will work as a one-to-one replacement of a delegate protocol with any number of methods.
Memory management: Delegates are usually weakly-referenced, since the delegate is usually a "parent" object that owns the delegator. However, blocks are strongly referenced, since blocks are one-use things that are not needed anymore once passed to the delegator. However, if you think about it, it is not really different. With delegates, typically the delegate method will perform some action on itself (the parent object). With blocks, in order to do this, the block would need a reference to the "parent". It is then this reference that needs to be a weak reference, to emulate the memory management of the delegate pattern. With blocks, the parent object code has more control over how the delegate will reference it, because it sets up the block.
In conclusion, it is possible to systematically convert any API using a delegate protocol into one that uses blocks, with what I described above -- for each delegate method, add one block property on the delegator.
Protocols and the designated delegate objects they talk to are quite different than block-based code, which is usually used to encapsulating a task and/or shipping it off to GCD.
I do see one place in the Apple's Block documentation that appears to match some of the functionality that delegates provide:
Blocks are particularly useful as a callback because the block carries
both the code to be executed on callback and the data needed during
that execution.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
The performance overhead of calling methods/properties in Objective-C is killing the performance of my iOS app; the Xcode profiler (aka, Instruments) attributes 70% of the latency to objc_msgSend, _retain, and _release.
In my code, so far, I make about 1100 calls to my XROpenGL class's instance method renderSprite(XRSprite) which is an overloaded method of renderSprite(XRSprite,int,int,int) which in turn invokes no less than five other methods, many of which access properties from XRSprite. As you can imagine, there's ALOT of messages being sent around.
Do I have any options apart from rewriting the critical sections of the code in C++?
Is that 6,600 calls per frame? I'll assume so for the sake of discussion, at 60 FPS for a total call count of 396,000 just for your explicit method calls. If you assume the pessimistic case, objc_msgSend's overhead (versus a C function call) is still only O(100) cycles. So on a modern iDevice you're looking at ~4% of your CPU time, very roughly. Not a huge deal. You might get a retain or two and corresponding releases for each call, but retain/release are relatively fast so we'd again be talking single-digit percentages. "Runtime overhead" of this nature of up to ~10% isn't considered egregious, generally, though it's not optimal.
So, the questions I have for you are:
Can you post your code?
Can you post more detailed profile information (e.g the exact breakdown between the various top 10 methods, as well as perhaps callstacks for the major ones)?
Are you sure the time is actually spent in objc_msgSend et al, and not merely in its children?
How many calls are you really making? As in measured, not assumed.
Can you use ivars instead of #properties, to remove some of the method calls?
Along those lines, are you caching the properties you do access when using them multiple times in one method?
Can you refactor to reduce the number of method calls, and/or use vanilla C functions for some things?
Obviously yes, you can rewrite key code in C++. But for mid-level drawing code you shouldn't have to; C++ is usually left to low-level constructs like vectors and quaternions and other such primitives.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I looked into some language for a while, and look at Objective-C's
[super message];
In fact, isn't it more accurate if there is some form like:
[self super#message];
? That's because we are still sending a message to the same object, which is self, but the message is a different one, which is the definition of message in the superclass. So isn't it more accurate that we don't change the word self, but change the message part instead?
Update: this is a comparison between Javascript's way:
Author.superclass.call(this)
and Author's superclass is Person. So it is the same as [this superclass's constructor], or is the same as [self super#init] (although init and constructor in Javascript are not exactly the same, but it is just to use as an example)
From a purely API standpoint (to which this refers) this makes no sense. If you look at the APIs relating to sending a message to self vs super, you would see the following:
objc_msgSend:
id objc_msgSend(id theReceiver, SEL theSelector, ...)
In this case, theReceiver is self, and theSelector is message (after that is the args list, which we won't get into right now).
Compare this to
objc_msgSendSuper:
id objc_msgSendSuper(struct objc_super *super, SEL op, ...)
Well wait a minute, that takes a totally different type as it's receiver! Looking into what super means gives us the following declaration:
struct objc_super
{
id receiver;
Class class;
};
An astute user would notice that this definition is invalid in ARC, but that's beyond the scope of this post.
What struct objc_super, then, allows us to do is to send a specific message to a specific class somewhere along the inheritance chain, which actually would allow us to skip huge parts of implementations if we wanted to.
So, with that said, the 'real' way you should do this would be the Java anonymous class (or C++) equivalent:
[MySuperclass.self message];
However, that is invalid because all types have the self message already declared, to point right back at themselves! So instead, we end up using the super keyword as a shortcut for
&(struct objc_super) { self, [[self class] superclass] }
instead.
Super is almost the same as self, except that you're not calling methods defined in your own class, but your super class instead. Adding hashtags to programming seems bad anyways...
It wouldn't be the same.
First, it would break the OOP paradigm, because you should not need to change the name of the method each time you subclass.
Next, suppose you have a class hierarchy like this:
class A, method foo and superfoo declared
class B, inherits class A, method foo declared
class C, inherits class B, method foo declared
Then calling [instanceOfC superfoo] will call the method in A, not method foo in B.
If you meant "super#" to be only a construction logic, it won't help either, because the dynamic resolution logic of methods in Objective-C won't be really respected.
Anyway, it's just a matter of syntax. the Objective-C language syntax is defined this way, you could argue that they should have used parentClass instead of super or any super# construct or whatever, that's just the language definition and they had to do choices anyway ;)
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I find myself often writing complex GCD / block based methods (comparable to the code snippet shown below).
How would you break up this kind of method in smaller
portions?
Would you rather GCD-enable the parsing methods in the managed
objects' code or would you rather keep the GCD code in the view
controller?
How can I run the NSURL request in the code below in the background
queue ([NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue] When I use NSOperationQueue
currentQueue, the completion handler does not get called.
Use a C function or a instance method to delegate certain processes (such as saving to the XML file).
Definitely keep it in the object's code. You are breaking MVC too much as it is,
Don't use NSURLRequest, use AFNetworking or RestKit instead.
I would separate that so you can actually see the MVC design in it. So I would have:
The UIViewController
A Manager Class to handle the interactions between the UIViewController, the NSURLConnection and the XML Parser
A class to handle the NSURLConnection (or any 3rd party you would like).
A class to handle the XML Parsing and posterior writing.
To establish communication I would use delegation. This way you would have different blocks of work. So when you need to change the XML Parse, just switch the class; if you need to use this logic somewhere else, just switch the UIViewController. Keep it simple and clean.
P.S: Sometimes, no matter what you do, the code just is, by it's nature, complex, please use comments, you will thank yourself later...
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
In #mmalc's response to this question he states that "In general you should not use accessor methods in dealloc (or init)." Why does mmalc say this?
The only really reasons I can think of are performance and avoiding unknown side-effects of #dynamic setters.
Discussion?
It's basically a guideline to minimize the potential for bugs.
In this case there is the (possibility) that your setter/getter may inadvertently make direct or indirect assumptions about the state of the object. These assumptions could be a problem when the object is in the midst of being setup or destroyed.
For example in the code below the observer does not know that 'Example' is being destroyed and could assume that other properties, which have already been freed, are valid.
(You could argue that your object should remove all observers before tearing itself down, which would be good practice, and another guideline to prevent inadvertent problems).
#implementation Example
-(void) setFoo:(Foo*)foo
{
_foo = foo;
[_observer onPropertyChange:self object:foo];
}
-(void) dealloc
{
...
self.foo = nil;
}
#end
It is all about using idiomatically consistent code. If you pattern all of your code appropriately there are sets of rules that guarantee that using an accessor in init/dealloc is safe.
The big issue is that (as mmalc said) the code the sets up the properties default state should not go through an accessor because it leads to all sorts of nasty issues. The catch is that there is no reason init has to setup the default state of a property. For a number of reasons I have been moving to accessors that self initialize, like the simple example below:
- (NSMutableDictionary *) myMutableDict {
if (!myMutableDict) {
myMutableDict = [[NSMutableDictionary alloc] init];
}
return myMutableDict;
}
This style of property initialization allows one to defer a lot of init code that may not actually be necessary. In the above case init is not responsible for initing the properties state, and it is completely safe (even necessary) for one to use the accessors in the init method.
Admittedly this does impose additional restrictions on your code, for instance, subclasses with custom accessors for a property in the superclass must call the superclasses accessor, but those restrictions are not out of line with various other restrictions common in Cocoa.
You answered your own question:
Performance may be a perfectly adequate reason in itself (especially if your accessors are atomic).
You should avoid any side-effects that accessors may have.
The latter is particularly an issue if your class may be subclassed.
It's not clear, though, why this is addressed specifically at Objective-C 2 accessors? The same principles apply whether you use declared properties or write accessors yourself.
It may be that the setter has logic that should run or perhaps the implementation used an ivar with name different from the getter/setter or perhaps two ivars that need to be released and/or have their value set to nil. The only sure way is to call the setter. It is the setter's responsibility to be written in such a way that undesirable side effects do not occur when called during init or dealloc.
From "Cocoa Design Patterns", Buck, Yacktman, pp 115: "... there is no practical alternative to using accessors when you use synthesized instance variables with the modern Objective-C runtime or ..."
In fact, for a class that comes and goes rather often (like a detail view controller), you want to use the accessor in the init; otherwise, you could end up releasing a value in viewDidUnload that you try to access later (they show that in CS193P...)
You can create the same problems by NOT calling the setter when allocating/deallocating.
I don't think you can achieve anything by using retain/release directly in init/dealloc. You just change the set of possible bugs.
Everytime you have to think about the order of property allocation/deallocation.