In a blog post I have just read:
'Swift allows us to extend classes from NSObject to get Objective-C runtime features for an object. It also allows us to annotate Swift methods with #objc to allow the methods to be used by the Objective-C runtime.'
I don't understand the term objective-C runtime features. Is it meaning that the code could be used in a objective-C project as well?
Quoting the apple docs
The Objective-C runtime is a runtime library that provides support for the dynamic properties of the Objective-C language, and as such is linked to by all Objective-C apps. Objective-C runtime library support functions are implemented in the shared library found at /usr/lib/libobjc.A.dylib.
That API is useful primarily for developing bridge layers between Objective-C and other languages, or for low-level debugging. You most likely don't need to use it.
Even when written without a single line of Objective-C code, every Swift app executes inside the Objective-C runtime, so that's why you can access it.
You can do things like swizzling
Objective-C Runtime
A lot of programming languages is ship with a kind of runtime/standard library which includes some core/base functionality
Objective-C Runtime is responsible for dynamism, memory management(allocation, reference counting...) and other language features. It is a layer between compiler and core libraries/frameworks.
Objective-C is dynamic language because shift focus from compile time to runtime:
Dynamic typing - figure out object's class in runtime. inheritance and other OOP principles
Dynamic binding - figure out invoked method in runtime. Message dispatch mechanism[About]
Dynamic loading - you are able to lazy-loading a new module in runtime.
Other features:
basic structures like class, object, variable, property, method
functions for working with these structures
Introspection - get/read info about class/object in runtime. For example instance variables, methods names, method arguments. class_getName
Reflection - modify its own structure and behavior. For example allocate new class, add variable, add method. class_addMethod
objc_msgSend - based on message dispatch
Swizzling - swap method realisation in runtime. method_exchangeImplementations. [Objective C], [Swift] swizzling example
Using [#objc vs dynamic] expose Swift's API for Objective-C and adds a dynamic behaviour for Swift code. It is useful when you need something which is not possible to do with usual swift approaches. Good examples are KVO, swizzling...
[KVO]
Objective-C vs Swift
Swift can use Objective-C Runtime library.
Swift has better performance(based on table dispatch) but Objective-C is more dynamic language
Related
As far as I understand Objective C / iOS is very dynamic language, so is it as dynamic as Ruby ? Does it have the equivalent of method_missing ? I asked the same question for js Does Javascript have something like Ruby's method_missing feature? and was disappointed that js does not support it yet.
Objective-C is dynamic, although having been a Ruby programmer, I would say it is not quite as dynamic as Ruby.
Objective-C does have an equivalent of method_missing. You'll want to override both forwardInvocation: and methodSignatureForSelector: and follow this important advice from Apple:
Important To respond to methods that your object does not itself recognize, you must override methodSignatureForSelector: in addition to forwardInvocation:. The mechanism for forwarding messages uses information obtained from methodSignatureForSelector: to create the NSInvocation object to be forwarded. Your overriding method must provide an appropriate method signature for the given selector, either by preformulating one or by asking another object for one.
Don't use doesNotRecognizeSelector: as Apple warns that it must always result in an exception being thrown.
Please see the NSObject class documentation for further details: http://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html
I've implemented this pattern based on the example of adding the same methods to a UITextField and a UITextView subclass: https://stackoverflow.com/a/19661059/171933
Enjoy!
I guess method_missing is a callback method that gets called when an object is missing a certain method. Well, you can use respondsToSelector method to check if an object can respond to a method. It's a method declared in NSObject protocol. So instead of getting method_missing called after realizing that some method is missing you can check it beforehands.
if ([myObject respondsToSelector:#selector(someMethodThatMightBeMissing:)])
NSLog(#"The method is missing");
I recently read about Dynamic Creation as one of the design pattern in Cocoa. However, I don't really understand how it works. So I need clarification from you who have implemented in your design.
What is it? Why and when would you use this design pattern?
I have read that you use NSClassFromString() to access the class. I assume that I use this when I want to use class that doesn't exist within the project I'm working on. Usually when I want to use certain class, I imported them in header. Does using this approach skip the #import process?
Class JavaArrayList = NSClassFromString(#"java.util.ArrayList");
I quote the code above as example. If do according to the code above, that means I can create a new JavaArrayList class and use the methods in it right?
JavaArrayList *foo = [[JavaArrayList alloc] init];
[foo useMethodBelongJava:doWhateverTask];
What are the benefits of using this design pattern? Especially in iPhone Development.
Your example appears to be using that pattern to instantiate a Java class. In the old days (up to about MacOS 10.4 I think), Apple had some technology called the Cocoa-Java Bridge, which let you use Java classes within Objective-C code. You had to instantiate them in the manner specified, because they didn't have Objective-C header files to import.
However, as of Snow Leopard, the Java Bridge no longer exists, so the code in your question won't work any more.
The recommended solution for calling a Java class from Objective-C is now JNI. Take a look at this question if that is what you're trying to do.
What is it? Why and when would you use this design pattern?
Coming back to NSClassFromString, it has other uses besides instantiating Java classes (which, as I mentioned, it doesn't do any more!). For an example, recently I wrote a library for parsing the response from a web service. In order to make it work with different web services, I had it read in a configuration file that described the data format it was expecting. For each field in the web service, my configuration file specified which Cocoa class to instantiate. Thus, in my code, I had a Cocoa class name as a string. To instantiate the object I wanted, I used NSClassFromString to turn it into a Class object.
Usually when I want to use certain class, I imported them in header. Does using this approach skip the #import process?
It can do. NSClassFromString will instantiate any class that is present at run time, so you don't need the header to be able to use it. If you don't have the header, you'll get a bunch of warnings of "may not respond to selector" whenever you try and use your newly instantiated class, as the compiler doesn't have enough information to be helpful. However, in many circumstances where NSClassFromString is useful, the header files aren't available.
See this link:
need advise about NSClassFromString
The only real benefit for iPhone was being able to reference classes from newer APIs and still target the old APIs. Since 4.0 you can do this anyway by setting the deployment target of your project. I can't really see any reason you would use it for iPhone programming any more.
This would only work for objective-C classes. You can't import java objects into your iphone app.
I am jus wondering what is mean by #dynamic in objective-c and how it works.any help please
#dynamic means that you will provide an implementation of those methods dynamically at run time.
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtDynamicResolution.html
has all the details, but basically using #dynamic means that you promise to provide implementations for the property promised methods at runtime.
In particular look here;
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html
for an example of how you'd construct your dynamic method and place it into the runtime.
Core Data uses this mechanism to provide the accessors. It's quite amazingly cool, once you dig into it :)
And as a side note, meta-programming in ObjC is not for the faint of heart, don't ship it till you grok it, otherwise your users will suffer.
I am quoting Apple's book The Objective-C Programming Language:
#dynamic
You use the #dynamic keyword to tell
the compiler that you will fulfill the
API contract implied by a property
either by providing method
implementations directly or at runtime
using other mechanisms such as dynamic
loading of code or dynamic method
resolution. It suppresses the warnings
that the compiler would otherwise
generate if it can’t find suitable
implementations. You should use it
only if you know that the methods will
be available at runtime.
You can find a pdf copy here.
Using #dynamic requires that you provide getter/setter methods yourself.
Instead #synthesize creates the getter/setter methods for you.
Is there anyway to add more fields (e.g. location and etc) to TTPhoto protocol?
I know that one way is to create my own protocol but that would require me to change a lot of stuffs in my view controllers. Is there any simpler way to achieve this?
Formal protocols are primarily a compile time conceit, to help you be more clear about your intentions. They're a relatively recent invention, before which all protocols were informal — they were part of the class documentation but not declared in the code. They have a runtime effect in that you can use some of the Objective-C runtime methods to query whether a particular class responds to a particular protocol (just as you can query whether a particular class responds to a particular selector), but no such testing will occur at runtime when you pass objects about.
Protocols are just a contract defining communications and don't specify behaviour. So there's no concept of inheritance. And there's no runtime list of the selectors included in a protocol, so the idea isn't particularly helpful.
Your best shot is to define an additional protocol that includes the extra functionality you want. Write your new objects to implement both protocols. Extend classes you don't want or have access to using category methods.
If you need additional storage to handle the new fields, then it's safest to subclass. You can actually add instance variables at runtime nowadays, but you'd need to drop down to the C interface to the Objective-C runtime and finding an opportunity to do so would require some hoop jumping.
This question is basically the inverse of this other question: Calling Python from Objective-C
I have implemented my iPhone application logic in Objective-C (obviously), and am now trying to re-use as much as possible from my XCode project in the server component to save on double-implementation. I have successfully loaded the CoreData data model from Python, however, can't see a way to actually call into the Objective-C logic from Python.
Basically I'm trying to access the Objective-C classes and methods in my iPhone project from Python to save myself duping out all the implementations.
Is this even vaguely possible, or is dupe-implementation the only solution here? Seems like the kind of thing Boost::Python might be used for, but I'm not really sure.
edit: Boost::Python won't work because it is C++ based and I need Objective-C. I knew there was a reason why that didn't work.
If your Objective-C code is in a framework and you would like to essentially write a Python application that uses your framework, then you can use objc.loadBundle, and then use objc.lookUpClass or NSClassFromString to get access to your classes. From there, you can use your classes like any other bridged Objective-C class.
If you're running your Python code within a process that already has the Objective-C runtime up, and your classes are already registered with it, then you can skip the loadBundle step.