Objective-C blocks and data execution - ios

When I'm reading the apple iOS Developer Guide, it explains me a bit about using Blocks (For use with GCD). It should pass some "snippit of code" into a objective-c object, and pass it to the other thread so it can be executed there. Wouldn't make the use of this exremely vulnarible to viruses and such? (data execution). Or am I missing some point here?

No - you can think of this 'code snippet' as a compiled, private, hidden function declared within your function (method…). IOW, it's as dangerous as any compiled function in your binary.

Even when you use ^blocks, your code is still pre-compiled.
I would say it's not more vulnerable then the rest of the "weak-linked" objective-c stuff.
The ^block is more something in the compiler / pre-compiler stage. I would say the resulting binary does not look much different (from a security perspective) then without blocks.

Related

How to deal with COM (un)initialization from a library perspective?

From reading several answers on this site, I learned that CoInitialize(Ex) should be called by the creator of a thread. Then, any code running in that thread can use COM. If that code happens to call CoInitialize(Ex) by itself, that would be harmless, because it would have no effect. It should not call CoUninitialize – that too should be done by the creator of the thread – but it won't if it inspects the (saved) result of CoInitialize(Ex) which would be S_FALSE. If the creator would not take responsibility for performing the initialization, the thread is at the "mercy" of that code to pick an appropriate threading model, which from then on won't be changeable.
What are the implications of all this for writing and using libraries?
When all code is your own, and you have a small team, it is manageable to organize the COM (un)initialization calls well. However, with libraries, the user shouldn't need to know how they do what they do, e.g. that COM is involved. I'd hate to have in documentation what can be dealt with in code. Also, no assumptions should be made about what thread the library's code will run in, unless it concerns VCL code.
Most open source libraries I've inspected call CoInitialize(Ex) in the initialization section and CoUninitialize in the finalization section, often even without checking if initialization succeeded. Some call InitProc instead, yet some first check IsLibrary.
What is it that they really should be doing? What if I'd write a unit myself that I'd want anyone to be able to use without much consideration? Wrap everything that touches COM in a thread and have that thread perform its own COM (un)initialization?
How bad is it really to be naive about it, like those open source units? When using them in a VCL app, their COM (un)initialization would always run on the main thread, which already has that performed first by Forms.TApplication.Create. Does that make the calls in the units innocent but useless? What if any of the units is listed in the .dpr before Forms? What about non-VCL apps, or DLL's? Should I not use such units before having them corrected? Should I somehow guard against what they might try to do, by preventively initializing COM always?
This is a rather complex question, but it all boils down to: how to (make it easy to) avoid trouble with regards to COM (un)initialization?
It's simple enough. Document that any consumers of your library must initialize COM. It's perfectly respectable and commonplace to do that. There's really nothing to worry about in placing such a requirement on the consumers of your library. If they fail to do what is required of them, that is their problem. As you point out, the creator of the thread has to take charge of initializing COM so you have no viable alternative.

Do we lose objc_retain()/objc_release() optimization for ARC if we override retain/release methods?

Edited: Some of you think ASDealloc2MainObject from AsyncDisplayKit doesn't really override retain/release. I modified the source code behind ASDealloc2MainObject (line 405-428 of _AS-objc-internal.h), added a printf() inside the overridden release method and did a few test runs on my iPhone. The log was printed as expected. My test code (including a new class that inherits from ASDealloc2MainObject) was compiled with ARC enabled.
I used to believe that overriding retain/release methods cannot be done under ARC. Turns out I was wrong. Such a technique involves a base class compiled under MRC and its subclasses compiled under ARC.
One good example is the Facebook AsyncDisplayKit. Lots of classes from the Facebook AsyncDisplayKit framework inherit from a base class called ASDealloc2MainObject. ASDealloc2MainObject is a class that compiles under MRC and overrides NSObject's retain/release methods. In the meantime, subclasses of ASDealloc2MainObject compiles and runs under ARC.
I have two questions:
Quite a few blog posts on the internet say that when ARC is inserting memory management code during compile time, it will insert low level C functions such as objc_retain() and objc_release() rather than their Obj-C equivalents [NSOject retain] and [NSObject release]. ARC does this because low level C functions could provide extra optimization, such as eliminating costly Obj-C message sending and canceling adjacent autorelease and retain calls. My question here is, if we use the MRC/ARC overriding technique, do we lose such optimization?
My second question is in some way related to my first question. What's the runtime behavior of objc_retain()/objc_release() if the target object's base class has overridden its retain/release methods? My guess is that these C functions are able to figure out the situation here. Instead of performing their regular optimizations (such as eliminating sending retain/release messages), they would in fact revert to the old way and actually sends out retain/release messages.
Quoting the documentation:
You would implement [the retain] method only if you were defining your own reference-counting scheme. Such implementations must return self and should not invoke the inherited method by sending a retain message to super.
Are you implementing your own memory management system? No? Then do not override retain or release.
Apple also advises against using reference counting for all Objective-C code. You are supposed to be using ARC.
ASDealloc2MainObject does not override retain or release. Old versions did but FaceBook realised that was a terrible idea and have updated their code to use ARC.
As for how exactly ARC behaves, the answer is "it depends". There are many different ways it can behave. Go read the compiler source code if you really want to know how it works.
That blog post you linked to is ancient and should not be trusted at all. Apple makes breaking changes to the compiler every 12 months and that means they've done so 3 times since the blog post was written. Since memory management is a performance bottleneck, that's where they make the most changes each year.
Sending a "retain" or "release" message to an object is outrageously slow. ARC and the Objective-C runtime both try to avoid sending messages as much as possible. One of the reasons the Swift language was created was to eliminate sending messages altogether. objc_retain() and objc_release() exist to avoid sending retain and release to an object. There might be situations where they do so but you can't rely on it.
I'd suggest that you write some code and try it. I'd expect that retain/release are not actually called from ARC code, because it uses (faster) function calls. So your overrides won't work when called from ARC. They probably work when called from non-ARC code.
That's to find out what happens. In practice, overriding retain/release in mixed ARC/non-ARC code will probably just get you into trouble.

How to do robust thread-local storage in iOS

I'm having some problems with apparently getting wrong results from pthread_getspecific in a library that's designed to link into various iOS apps.
I see that Apple writes:
Cocoa and POSIX store the thread dictionary in different ways, so you cannot mix and match calls to the two technologies. As long as you stick with one technology inside your thread code, however, the end results should be similar. In Cocoa, you use the threadDictionary method of an NSThread object to retrieve an NSMutableDictionary object, to which you can add any keys required by your thread. In POSIX, you use the pthread_setspecific and pthread_getspecific functions to set and get the keys and values of your thread.
Does that mean that neither the Cocoa nor POSIX TLS functions can be expected to work in library code when we don't know whether the code that calls us is already using one or the other?
How does one get to store and retrieve a thread-local pointer robustly in these circumstances?
Is there a native Darwin TLS support API we should be using instead of either Cocoa or POSIX?
I believe the point that Apple's docs are making is that you cannot use pthread_setspecific to set a value and then expect it to be available in threadDictionary. I wouldn't expect them to directly interfere with each other; they're just separate.
That said, if this is iOS-specific code, then the strongly preferred way to manage this is with GCD rather than POSIX threads. GCD offers the equivalent of TLS in the form of dispatch_get_specific, dispatch_queue_get_specific and dispatch_queue_set_specific. But it also provides much better thread management than POSIX threads.
If you don't mind using C++, boost has thread_specific_ptr. It supports iOS. If you don't want to use C++, the implementation probably offers some hints on how to make it work without a lot of external dependencies.

non ARC classes in an ARC compliant project?

I am working on an iPhone app which does some video processing, I had to include to classes that are not ARC compliant ( dealloc , releasing stuff ). So I manually went and made them arc compliant.
Later on I discovered the compiler flag for any class that can make it non ARC in an ARC project -fno-objc-arc.
My question is, if I do flag those classes with the compiler flag, what are the reprecussions of this? performance hit? is it a good idea? my app iOS 5.0 and up. I couldn't find any resources that talk about pros and cons of doing this.
You ask:
If I do flag those classes with the compiler flag, what are the repercussions of this?
The only thing I believe you need to worry about is to make sure that the non-ARC library follows Cocoa naming conventions associated with memory management (e.g. only return objects with +1 retainCount if the name begins with alloc, new, copy, or mutableCopy). Otherwise your ARC won't be able properly manage the resulting object. Most well written classes will conform to this pattern, so you should be perfectly ok using the fno-objc-arc flag, but it depends entirely upon the class in question.
[Is there a] performance hit?
There are no practical performance issues.
[Is] it a good idea?
All things being equal, I generally like to convert the code to ARC. A couple of situations where I might refrain from converting:
It is a library for which there is active development, and if I create my own personal ARC fork, I'll lose out on the future revisions of the library.
The library is incredibly complex and/or has constructs that are not easily converted to ARC.
Bottom line, if I can convert to ARC, I will. Usually in this process, I'll do the necessary testing to make sure I'm comfortable with the library, that there are no leaks, etc., so it's a productive (if annoying) process to go through. We're all responsible for the code we include in our projects and I don't think one should ever integrate code without going through some due diligence that is a natural by-product of an ARC-conversion and testing process.
If I convert to ARC, I offer to contribute the conversion back to the original author (e.g. via a GitHub "pull request" or whatever mechanism the author is open to) so it can be integrated into the code base.
At first glance, there are no performance issues with using or disusing ARC. ARC is basically normal reference counting, it's just not the programmer who inserts the release calls, but the compiler.

NSXMLParser samples and ARC

I have seen many samples of NSXMLParser and understand how it works. For example, this one is very good:
http://wiki.cs.unh.edu/wiki/index.php/Parsing_XML_data_with_NSXMLParser
All samples I saw use Release to release temporary objects at some point during parsing which is OK. But if I switch on ARC, I don't have access to release at all. How does the sample code change then?
For example, please look at the above code (link) and explain how would you change it with ARC ON?
Thanks.
For a discussion of how one goes about making non-ARC code enabled with ARC, I'd refer you to the Transitioning to ARC Release Notes. As Midhun alludes, you will be replacing retain references with strong references and eliminating release and autorelease. You'll also be removing calls to [super dealloc]. So the conversion isn't hard, but there are a number of items to be conscious of.
Having said that, I disagree with your assessment that this example code is "pretty good." With no insult to the original author, it's a little outdated, and as such, is applying historical conventions rather than the modern contemporary practice (e.g. explicitly declared ivars for properties, not using underscore for ivar names, etc.). I also noticed a few bugs in the code (minor things like a missing property, more significant things like a bug in the foundCharacters routine, etc.).
I've cleaned up the code (both converting it to ARC and addressing a number of these issues) and have uploaded it to a repository on GitHub. Note, I've done two things:
I've modified the code to be a little more contemporary in its practices (this is the UsersParser class) and fixing a few of these little bugs;
I've also made a rendition of this code which is a little more flexible, the XmlArrayParser, where the parser class isn't hard-coded for the Users XML file that the example uses. The method that calls this has to understand what elements we're looking for, but the parser itself doesn't care.
I hope this help.
When you convert it to ARC there will not be any
retain
release
autorelease
keywords.
For better understanding you should convert that sample code using Xcode ARC conversion Tool.
You'll get a better understanding when you complete that.
Please refer this tutorial for assistance.

Resources