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.
Related
I am trying to search to prevent the Method Swizzle in my current library but more or less every documentation or blog post that i found are about how to implement Swizzling.
There are couple of question that i have regarding Method swizzling that i could not find all across.
How to detect the Method Swizzling at runtime?
In case there is a Method Swizzle how to prevent it ?
I know the dangers of method swizzling and have already gone through the related posts here but could not find the related information to prevent it.
If there is any documentation or blog post that available on the above topics, I would really appreciate the assistance.
Avoiding method swizzling is simple; use functions rather than methods (i.e. do things the old-fashioned way without objects, in C++, or at least in Core Foundation). But if you're using the ObjC runtime, you can be swizzled.
You can in principle detect swizzling by caching all your IMP pointers, for example using class_getMethodImplementation in something like +load or maybe a C++ constructor on a global variable (which get run before main()), and then re-checking all your IMP pointers at various times to make sure they haven't changed.
That probably wouldn't be too hard, but it's difficult to imagine what all of this would achieve. If someone has your framework binary, it wouldn't be a major effort to to patch it to remove your check. Somewhere in the source code, there's got to be a if (swizzled) { ... }, and that's going to translate into a branch-if conditional instruction in the assembly. You stick a debugger on the system, wait for the branch to "ah! we're swizzled" to occur, note the point where it happens, and patch that byte to be "branch-if-not" or just add an unconditional jump.
Slowing that attack down, even a little, requires substantial obfuscation. There are techniques (that mostly don't work that well), but they only work by being kept secret. That's the difference between obfuscation and security.
Short answer is you really can't achieve this in any stable way. That means you either need a team devoted to constantly coming up with new, more advanced obfuscations and updating them regularly as new attacks emerge (i.e. how a company like Blizzard or Apple prevent hacking), or you'll need to find a way not to need this.
Simplest answer? Work mostly in C++ and use ObjC classes as little as possible (which will prevent swizzling, but not reverse engineering or patching). Or accept that swizzling is not avoidable.
(BTW, if there were even a "I'm willing to do whatever it takes" answer to this question, then Apple would just use that technique to make jailbreaking impossible. The fact that iPhones get jailbroken regularly suggests the difficulty of the problem.)
We've used greenrobot's EventBus library extensively in Android development, and we're looking for something similar for iOS. It looks like a sort of event bus is already built in in the form of NSNotificationCenter, as well as quite a few third-party solutions that are essentially wrappers for this functionality with some added features for convenience.
However, we're rather accustomed to the concept of events being discrete objects with clearly defined member variables, with the additional benefit of polymorphism from being object-oriented. Most iOS libraries I've found so far have you passing in an arbitrary event name and an arbitrary bundle of data, which is a little too loosey-goosey for our purposes.
The only example of the object-oriented design I've found so far is Tolo, which looks great at first glance, but hasn't been updated in about three years, save for some minor documentation details. Also, given its age, it's still written in Objective-C, which could lead to some difficulties if we need to look under the hood at some point (we're pretty committed to Swift).
Are there any other options I haven't come across yet?
No reason why you cannot create a specific class that you pass as the object in NSNotificationCenter. Its true that many examples are lazy in this respect, obj-c is traditionally fairly loosely typed which probably explains this.
Its also fairly common (in projects bigger than online tutorials) to use a constant of some sort as the event name, either a class constant or a #define if using obj-c.
For anyone in 2017+ interested in this, I wrote this thing ages ago:
https://github.com/MooseMagnet/DeliciousPubSub
It offers strongly-typed pub-sub.
Under the hood it still uses strings as a key (just uses the name of the type) but you get compile-time goodness...
I left it sitting for a while under the assumption no one was using it, but recently received a PR from someone who had updated it for Swift 3. Wow, such OSS.
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.
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.
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.