Objective-C++: is there an overhead in generated code compared to Objective-C? - objective-c

Let's say you have an Obj-C module written in pure Obj-C. Does switching the extension to .mm mean that the generated code will be larger due to C++ exception handling (or something else maybe)?

There are two possibilities: You either need Objective-C++ or you don't. If you don't need it, don't use it. If you need, well then you need it, so if there is memory overhead, there isn't much you can do about it.
Don't switch to Objective-C++ just for fun. I wouldn't use it for anything other than writing bridging code between Objective-C and C++.

Related

Swift optimization not working?

I am trying to decide between Swift and Objective-C for my app. Currently I am testing performance for operations that will happen a lot in the app.
I have written a testapp that downloads a json file and puts it in a NSDictionary like this:
var err: NSError
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(JSONData, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
println(jsonResult)
And when I test it, Objective-C seems to be faster everytime. But there's no difference in using the optmization (-Ounchecked) and no optmization(-Onone). I know the println is the biggest slowdown in both Objective-C and Swift.
Does the lack of optimization have anything to do with the fact that it's barely possible to optimize that line?
As you say, there's nothing in the above program to optimize. You can check for yourself by looking at the assembly output, but I would expect them to be almost identical.
In general, things heavily involving Cocoa are going to be as fast or faster in ObjC today than Swift. The ObjC compiler has decades of work behind it, and Cocoa has decades of ObjC-specific optimization. There is nothing Swift can do to make a call to an existing Cocoa method faster. NSJSONSerialization is the same class in ObjC and Swift.
It is possible for Swift to be faster than pure ObjC in things that you would traditionally use C or C++ for anyway. It is possible for an [Int] to be faster than an NSArray of NSNumber for certain operations (but see this question before you assume that NSArray is slow), just like it's possible for vector<int> or int[] to be faster for those same operations (and for roughly the same reasons). But that's a poor reason to choose Swift. If numerical calculations are your major problem, and performance is at a premium, then C and C++ have decades of optimization behind them. Swift might beat them here and there, but C and C++ are known quantities.
But micro-benchmarks like these are useless in working out performance questions. They're not going to tell you much about your app's total performance. That comes from profiling real code, and then optimizing your bottleneck. And in some cases that might mean moving some piece of Swift code into ObjC (or C or C++), just like we've long converted pieces of ObjC to C or C++ when we needed to improve certain kinds of performance.
Swift is neither easier to read nor understand than ObjC. It is in certain cases easier to write (though often it is much harder). It is much easier to write correct code with fewer bugs because of better typing, and that's why I think it's going to be a great language. But not because it's "easier."
Swift appears easier because its syntax is slightly closer to Java and JavaScript and many people who are evaluating it have a Java and JavaScript background, but Swift's dramatically more complex features and rough edges when working with Cocoa make understanding much more difficult. Why do you need as NSDictionary in the above code? How is a new programmer supposed to know that? The equivalent ObjC has no such weirdness. When you start doing more work, you'll discover many very confusing compiler errors any time AnyObject shows up (and it shows up all the time with Cocoa). Don't be fooled by the parentheses versus square brackets. ObjC is a much simpler language with years of tutorials, StackOverflow Q&A, books, and training available. (Also the ObjC compiler almost never crashes.)
IMO, if you are uncertain, then use ObjC. ObjC is what Cocoa is designed for. ObjC has a well-established compiler. ObjC is easier to learn (it's harder to just dive into and start hacking at things, but it's easier to actually learn).
As Swift settles down (and it's quickly settling down), you can convert parts of your app to Swift. Swift was designed to allow you to mix it this way, and it's getting easier to do that in practice (particularly with the new ObjC annotations). But if you have any serious deadlines ahead of you, I strongly recommend ObjC.
On the other hand, if you don't have a serious deadline, and you like Swift better, go for it. I think it's going to be a great language some day.

Template in Objective C?

Everything is in the title :)
Is there any templates in ObjC ?
I need equivalent of c# :
public class MyClass<T> : Message
in ObjC .
Any helps will be strongly thanks :(
There is no such ObjC feature. While ObjC++ does exist, I strongly discourage its broad use. It has many problems from poor tool and debugger support, to poor compiler optimization, to degraded ARC performance.
Generally templates are not required in ObjC because it is not a strongly typed language. An NSArray can hold any object, so you don't need to use a template to get the right type. Do you have a specific problem you're trying to solve? There is likely a better ObjC solution.
Obj-C supports templates since Xcode v7. It is named generics:
Lightweight generics now allow you to specify type information for
collection classes such as NSArray, NSSet, and NSDictionary. The type
information improves Swift access when you bridge from Objective-C,
and simplifies the code you have to write. For example:
NSArray<UIImage *> *images;
NSDictionary<NSString *, NSURL *> *resourcesByName;
Look for "Objective-C Language Changes" section in
https://developer.apple.com/library/content/documentation/Xcode/Conceptual/RN-Xcode-Archive/Chapters/xc7_release_notes.html
By the way, Xcode supports adding C++ classes through the New->File. Using the extern "C" {} construct in C++ means you can provide as much or as little C-callable interface as you need, which you can then call directly from your Objective-C code, since Objective-C is a superset of C.
Having said that, it's probably a good idea to stick within the Objective-C paradigm unless you have a pressing reason to move outside it, such as the need to incorporate a body of existing C++ code into your project. (That's not to say that Objective-C is a "better" language, which is a different matter entirely.)

Any downside to never creating ObjC files but always creating ObjC++ files instead?

By default Xcode creates both an .h and and an .m file when you ask for a new ObjC class.
Everything works fine until you need to refer to any C++ file elsewhere in your project and start #import ing it into either your .h or .m file
At that point, the ObjC compiler gest utterly confused and throws mountains of parsing errors, and you the user (that is to say: me) get even more confused until such time it hits me: of course I should make that file an ObjC++ file instead.
The options are:
tell Xcode that this particular file, even though it is a .m file
really is an ObjC++ file, or
rename that file to .mm.
The first option is not very palatable to me, because that file really is ObjC++ regardless of the what the project thinks it is.
The second option is not good either as it screws up the Git repo which then 'forgets' that there used to be another .m file which really is the history of this 'new' .mm file.
So I have decided from now on to always rename any .m file that Xcode creates for me to .mm first thing after creating it so that I won't loose the history.
It has worked well for me so far, but I have this slight worry in my head, that there might be some corner case where I would really want to have an ObjC file and not an ObjC++ file.
What would those corner cases be? Anyone is aware of any ObjC++ file which happens to NOT contain any C++ reference but would choke the ObjC compiler in some way, just by virtue of being an .mm file?
And if there are no downside, why not just deprecate the use of .m forever and stick to .mm instead?
Parsing C++ is much slower than parsing ObjC, so ObjC++ files have significantly longer compile times. I'm not certain if this overhead will apply to ObjC++ files that contain no C++, but it would make a certain amount of sense that it's harder to parse just because the compiler needs to look for C++ constructs.
Also, the C++ type system has a few slightly different rules from C, that are applied to ObjC/C code in a C++ file as well. I don't recall the details, but it's not going to be harmful; just might require a few extra casts.
There is no downside, although there are two methods created on behalf of you (.cxx_construct and .cxx_destruct), but they are only used for crafting and destroying C++ objects when you create/dealloc an instance. If your class has no C++ members, these functions do nothing and add only an really extremely low overhead. Otherwise, you still have C functions generated for your Objective-C methods, not C++ functions.
Create an Objective-C++ file template so you get a .mm file instead of a .m file when you create a new file. Make a copy of Apple's Objective-C class templates and rename the .m files to .mm. More detailed information on creating Xcode 4 file templates is available in the following article:
Creating Custom Xcode 4 File Templates
Language incompatibilities aside, one reason to avoid an entirely .mm project is that you might end up being tempted to start sections of your methods in c++, which will result in a project written in a (relatively obscure) hybrid of two languages, and will only be understood by people who know both. (I have done this before)
A nice way to avoid cluttering your obj-c headers with c++ is to declare instance variables in your implementation file (which is allowed as of xcode 4.2/clang 3.0, possibly earlier). Eg:
#implementation MyClass {
std::vector<int> myVector;
}
This helps to keep the points of contact between objective-c and c++ minimised.
I use .mm file exclusively for my iOS code and have never had any issues. Yes, my compiles are a little slower in that a clean compile takes 15 seconds vs 10 seconds. At least on a iMac, it's not significant.

GCC_ENABLE_CPP_EXCEPTIONS and Objective-C

I have a pure Objective-C project (no C++ anywhere). Can I turn off GCC_ENABLE_CPP_EXCEPTIONS or do Objective-C exceptions rely on this?
If you're not using any C++ code, you can turn it off (it only applies to C++ code). Or you can leave it on -- it won't really matter either way.

Do "dynamic ivars" break the "strict superset of C" paradigm for Objective-c?

Thank you to Yuji for answering another question I had and pointing me to this article about dynamic ivars in Objective-C.
However, as explained in my other question the sizeof operator now behaves inconsistently. In short, sizeof will not take into account dynamic ivars from outside the class .m file but will take them into account inside the .m file after the #synthesize declarations that create the dynamic ivars.
So my question is does this break the idea that Objective-C is a strict superset of C?
No. All valid C code remains valid Objective-C code with the same meaning it has in C, so Objective-C is still a strict superset. Keep in mind that a superset is allowed to have features not found in a subset — that's the whole reason Objective-C can have all the additional capabilities and syntax that it does while remaining 100% C-compatible.
What this does affect is the implementation detail that Objective-C classes are essentially C struct types with a set of functions that act on them. Note that similar functionality to objC_setAssociatedObject() could be implemented for a CoreFoundation-style pure C struct without changing the C language itself at all — and it would have the similar side effect of making sizeof() not give a fully "accurate" idea of all the data the struct encompasses.
No. If you run Objective-C code through a C compiler it never would have compiled anyway. If you run C code through an Objective-C compiler it will behave exactly as if you had run it through a C compiler (barring compiler bugs).
If you ever find yourself writing sizeof(MyObjectiveCClass) you are almost certainly doing something horribly wrong that will be completely broken.