I'm working on writing my own Objective C wrapper around a minimal set of OpenAL functionality. One use case I'm trying to enable is transport controls after telling a sound to play like pause/stop/resume operations. I'm interested in trying to do this using what has been described to me as an "opaque type" or an id that conforms to a protocol in Objective C lingo. Does returning one of these make sense in this case, or would it be easier to just directly return an object and tie myself to that implementation?
And assuming the opaque type is the right approach, what would be a good name for the protocol? Right now I'm following this paradigm and calling the protocol OpenALPlaybackDelegate. I feel as if delegate doesn't really quite fit the model since the communication is happening the other way around.
An opaque type in this case is basically just a pointer that's used in Apple's C APIs in place of an object. Unlike a normal pointer to a struct full of stuff in C, the opacity in 'opaque types' comes from the fact that the header files don't expose the struct definition. The only way to deal with them is through the C functions that are exported. You see this in two places:
C APIs: Core Graphics, Core Audio, Core Foundation, Grand Central Dispatch. C has no objects. Apple has a bunch of types like CGFoobarRef that represent pointers to some sort of thing made with a function like CFFoobarMake();
Bridged APIs. Cocoa functionality is made available to C code through "the toll-free bridge", so you can generally get a handle on a say an instance of a Cocoa class in C world as an opaque type. Again, these generally end with Ref. All the Cocoa container classes, for instance, are available to C consumers through the Core Foundation toll-free bridge.
Relevant Apple documentation
If the consumers of your protocol are Objective-C libraries, which I'm going to assume they are, because that's the only way to use protocols, then no, it doesn't really make sense to expose access to any of your stuff as an pointer to a C struct filled with data and function pointers that are hidden from client code and exposed through a set of C functions.
Also, the reason to do this, for Apple, is encapsulation, data-hiding, etc. All it does is keep people from being able to muck about directly with the internal state of an object from C land, or write code that depends on it, because C lacks features like classes and ivars (well, Objective-C doesn't really have private ivars either but it at least has secret ones).
I would think writing an Objective-C wrapper around OpenAL, exactly what you would not want to do is return opaque types. You should return Objective-C objects that hold opaque type references with accessors/mutators that call the relevant functions on those references.
Related
In ObjC, it is using Messaging, static binding, dynamic typing, dynamic binding, dynamic method resolution, dynamic loading, introspector and so on.
Importantly, the core method objc_msgSend is responsible for taking the selector you're sending and the object you're sending it to, and looking that up in the class method tables to figure out exactly which piece of code is supposed to handle it.
My concerns here are:
Is Swift doing something similar like ObjC on runtime?
How does Swift runtime find the implementation code for some object/class method?
In ObjC, classes and objects are compiled to some runtime types such as C struct on runtime. Then what are such classes and objects compiled to on runtime in Swift?
Does Swift runtime have something like class / meta class / isa pointer / super pointer?
In short there are Dynamic and Static types of method call dispatching.
Static - the function address to be called is determined in the compilation time, so that expense of such call is similar to C-function calling. This mechanism is used for private methods or final classes methods call dispatching.
Dynamic dispatching is mechinism which allows to implement polymorphism concept of OOP - the function address to be called is determined in running time. Swift has two subtypes of it:
2.1. Obj-C - you already described in the question. This mechanism is used when object inherits from NSObject or calling method has #objc prefix.
2.2. Virtual table based (like in C++) - there is similar witness tables. What it does during method call dispatching is just single arithmetic operation - calculation of actual function address based on function offset in the base class witness table and the object class witness table location. So that's a relatively cheap operation comparing to Obj-C. It explains why "pure" Swift approximates to C++ performance.
If you don't mark you method with private keyword or your class is not final and same time you class is "pure" Swift (it does not inherit NSObject) then this virtual table based mechanism is used. It means that all the methods by default are virtual.
P.S.
Helpful link for proving my vision regarding "Types":
https://developer.apple.com/swift/blog/?id=27
"Subtypes" explanation is based on my understanding.
Often when debugging (and out of curiosity) I expand the object explorer at left and see lots of '_' prefixed fields of a UIKit object, say, UINavigationBar, as pictured below.
There's lots of fields like _titleView that must be deeply private, not even revealed when jumping to the class definition.
Furthermore the object explorer reveals classes like UINavigationItemView which the documentation doesn't even have, and which the lldb prompt denies knowing about.
(This is probably part of the issue: UINavigationItem.h has __attribute__((visibility("hidden")))
#interface UINavigationItemView : UIView { ... })
Again mostly out of curiosity but would like to shed light on the matter.
Those instances variables come from Objective-C runtime type information
The Objective-C runtime stores information about the iVars of classes, in the form of names and type encodings (https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html)
The debugger knows how to poke at that runtime information, and produce a representation of the internal guts of your object from that information
That information is, however, not used by the language when making Objective-C types available to your Swift code
Part of the story is that this runtime information may be incorrect or incomplete, which would of course be solvable by blacklisting the erroneous cases (NSURL comes to mind as a typical example, and there are a few more caveats)
However, in general, the iVar information from the runtime is implementation detail and definitely not part of the public interface of a type. It is useful to see in the debugger, but it is not exposed as part of the type's interface in Swift. That explains the fact that, while you can see the data in the variables view, you can't actually evaluate expressions involving it
I am working on a project in iOS using Xcode. I want to include a library written in C. But I don't know how to use C library in Objective-C.
Here is the link of Library: https://github.com/bcl/aisparser
Can someone help me?
You're going to hit one obstacle in the form of what's called "name mangling". C++ stores function names in a way not compatible with Obj-C.
Objective-C doesn't implement classes in the same way as C++, so it's not going to like it.
One way around this is to implement a set of simple C functions which call the C++ functions. It'll be a good challenge to keep the number of C functions as low as possible! You'll end up with a nice compact interface! :)
To declare these functions in a C++ file, you'll need to mark them as C with:
extern "C" int function_name(char *blob,int number, double foo) {...}
This disables the standard name-mangling.
Build a header file with the prototypes for all these functions that you can share with your objective C code.
You won't be able to pass classes around in the same way (because your ObjC code can't use them), but you'll be able to pass pointers (although you might have to lie about the types a little).
This question is specifically focused around static libraries / frameworks; in other words, code that other people will eventually touch.
I'm fairly well versed in properties, since I started iOS development when iOS 6 was released. I have used hidden properties declared in interface extensions to do all of my "private" property work, including using readonly on public facing properties I don't want others to modify and readwrite within interface extensions.
The important thing is that I do not want other people who are using these static libraries / frameworks to be accessing these properties if I don't allow it, nor writing these properties if I let them read it.
I've known for a while that they could theoretically create their own interface extension and make my readonly properties readwrite themselves, or guess the names of hidden properties.
If I want to prevent this, should I be using ivars with the #private tag with directly declared ivars? Are there potential downfalls to doing it this way? Does it actually get me an additional measure of security, or is it a red herring?
Under ARC the only mode supported by properties and not instance variables is copy - so if you need copy use a property.
If you declare your private instance variables in the #implementation section:
#implementation MyClass
{
// private instance vars
}
then it takes serious effort to access them from outside the class. As you say accessing a "private" property just takes guessing its name - or using the library calls which tell you.
Is it worth it for security? YMMV. But its a good coding practice regardless.
Addendum
As the comment trail shows there has been much discussion over my use of serious effort.
First let's be clear: Objective-C is in the C family of languages, they all allow the programmer to just about anything they choose while staying within the language[*] - these are not the languages of choice if you want strong typing, access restrictions, etc., etc. within your code.
Second, "effort" is not an absolute measure! So maybe I should have chosen the word "obvious" to qualify it rather than "serious". To access a private property just requires the use of a standard method call where the object has type id - there is little clue in the code that the method being called is hidden. To access a private variable requires either an API call (a runtime function or KVC call) or some pointer manipulation - the resultant code looks nothing like a standard variable assignment. So its more obvious.
That said, apart from uses requiring copy, under ARC there is no good reason to use a private property when a private instance variable will do. For a private variable fred compare:
self.fred = 42; // property access, may involve a call (if not optimised out)
_fred = 42; // common way to bypass the accessors and get at the underlying var
fred = 42; // direct access
Take your pick, there is no right answer, but there isn't a wrong one either - this is the realm of opinion (and that is of course an opinion ;-)). I would often pick the last one, private variable - clean & simple. However #RobNapier in his answer prefers the use of properties.
[*] Note: once you consider linking to external code, say written in assembler, all bets are of in any language. At that point you have to look at the "hardware" (real or virtual) and/or "OS" to provide protection.
You should use private ("hidden") properties here. There is no "security" risk. The "attacker" in this scenario is the caller. The caller has complete access to all memory in the process. She can access anything in your framework she wants and there is absolutely nothing you can do to stop that (nor should you). This is true in any language. You can bypass "private:" designations in C++ as well if you know what you're doing. It's all just memory at the end of the day.
It is not your job to protect yourself or your framework from the caller. You both have the same goal: correct program behavior. Your goal is to protect callers from themselves. Make it difficult for them to use your framework incorrectly and easy to use it correctly.
So, you should use the tool that leads to the most correct code. And that tool is properties, and avoiding directly ivar access except in init and dealloc.
Will usage of static variables expose them to a danger of being modifiable from anywhere ?(In context of Objective-C). If yes, can someone suggest best alternatives for using shared variables across all classes ?
Is using too many static variables in Objective-C a bad practice?
Yes. Of course, "too many" has not been quantified and is subjective. Really, global/static variables are very rarely a good thing -- very convenient to introduce and very difficult to debug and eliminate. Also rare is the case that they are good design. I've found life far easier without them.
Will usage of static variables expose them to a danger of being modifiable from anywhere? (In context of Objective-C).
It depends on where they are declared and how they are used. If you were to pass a reference to another part of the program, then they would be modifiable from 'anywhere'.
Examples:
If you place them so that only one file can "see" the variable (e.g. in a .m file following all includes), then only the succeeding implementation may use it (unless you pass a reference to the outside world).
If you declare the variable inside a function, then it is shared among each translation and copied for each translation in C/ObjC (but the rules are very different in C++/ObjC++).
If yes, can someone suggest best alternatives for using shared variables across all classes?
Just avoid using globals altogether. Create one or more type/object to hold this data, then pass an instance of it to your implementations.
Singletons are the middle ground, in that you have some type of global variable/object based abstraction. Singletons are still so much hassle -- they are categorized as global variables and banned in my codebase.
Static variables are local to the translation unit, so the variables are definitely not modifiable from anywhere. Globals, which are closely related to statics in that they are allocated in the same memory area, are modifiable from anywhere, and that's their main danger.
When you need a group of variables to be accessible from anywhere in your project, the common approach is implementing a singleton that holds related data, and contains methods for processing that data. In MVC apps implemented in Objective C the model is often accessed through a singleton model object.
My scenario involves a number of static variables declared in the .h file & they are assigned values in specific methods declared in those .h files.
If you declare statics in the header, they become "disconnected" from each other: each translation unit (i.e. each .m file) gets its own set of statics from the header. This is usually not what you want.
If you make these variables global, you end up with a plain C, not an Objective C, solution. You should put these variables in a class as properties, and move function implementations with them into the methods of your class. Then make the class a singleton as described in the answer linked above to get a solution that is easier to understand than the corresponding solution based on globals.