I have an NSMutableArray in which i want to add those objects which conforms the ObjectType. Is there any way i can get the ObjectType declared using light weight generics so when adding an object i can check whether the object is about to insert is ObjectType; if yes insert it else just forget it.
Thanks.
In Objective-C all type analysis is done at runtime and only at runtime. (The compiler gives warnings at compile time, but the produced code is bit-identical to code with any other object type.) The lightweight generics are for Swift. We didn't need that in the past 30 years. (Wow, this is really long in computer sciences.)
So, any code related to the mutable array with or without type specifier is identical. For Objective-C a static type information is the wrong thing. Even there would be a way to do that, it would be anticonceptual.
So: No.
Why do you want to do that? Don't do it.
Related
When generating an NSManagedObject subclass xcode creates two extra files MyObject+CoreDataProperties.h & MyObject+CoreDataProperties.m to keep the CoreData stuff away from our own code.
This is nice but I noticed in a WWDC clip that they didn't have the +CoreDataProperties.m file in their example. So I tried removing these in my code and everything compiles and runs fine without them, they don't appear to be necessary at all.
Are they required in some way that I've overlooked, or if not, then why does xcode generate them at all?
The short answer:
No, it is not necessary.
The long answer:
Objective-C is a dynamic typing, late binding programming language. In a short form that means, that every type decision can be made at runtime instead of compile time and you can access properties of an and send messages to an object without knowing its type (class).
But it is not necessary for the Core Data framework and you as the user of Core Data and your model to know the type of an managed object for a entity type. It is even not necessary to have a specific type for an entity type. (I do not generate the classes very often and if I do, I do it manually.) Therefore in contrast to other programming languages these generated classes are not necessary to give the compiler a type.
However, the compiler wants to see at least every method at least one time to get the signature (parameter typing). Otherwise it would warn. Even it is possible to have working code like this …
NSManagedObject *person = …
NSString *firstName = [person firstName];
… for an entity type Person with a property firstName, the compiler will warn you, that he does not know anything about a method –firstName.
Instead you can type something like this:
NSManagedObject *person = …
NSString *firstName = [person valueForKey:#"firstName"];
(The compiler knows -valueForKey:, since this is a method declared in NSObject.)
Beside this you get benefits like code completion, check for typing errors and so on. But you do not need to use the code generation tool of Xcode. Simply declare such a class and at the properties at the interface. The accessors can be dynamically generated using #dynamic. (Personally I nearly never use the static code generation.)
Edit: Added the result of the discussion in the comments.
So having the interface (".h-file") of the category, the compiler knows enough to compile the whole code without warnings. This will work at runtime, if it is guaranteed – or checked at runtime – that a corresponding message can be dispatched. This makes sense in many situations from the very beginning of Objective-C, i. e. for forwarding and informal protocols. In the context of Core Data it is used to dynamically generate standard accessor methods. Everything works fine without any implementation.
However, one wants to have an implementation for some reasons, i. e. housekeeping on value changes. In such a case it is useful to have a stub implementation you can edit. But for standard behavior it is not necessary.
I am writing a bridge from a language I am developing and ObjC.
There are several nice introspection C functions in the objective C runtime and I am able to retrieve arguments types for methods using method_getTypeEncoding.
The main problem is with object arguments which are returned as id (encoded as #) but what I would need is the real objc class name like NSString or NSNumber.
Is there a way to solve this issue without parsing the .h files?
Knowing something is an id allows you to know the size of the parameter, which is important when writing a scripting interface. Add another layer where you can dynamically verify assumptions using things like
[objectPassedIn isKindOfClass: [expectedType class]];
You want to be careful hardcoding things like, "Oh this is a string so look for __NSCFString" - because there's no way to know you'll get an instance of __NSCFString or another type. NSString is a class cluster - You could get any custom implementation back when using one.
The actual type of objects is not important to the Objective-C Runtime so you need to add your own layer. You might be able to get some useful info using Clang/llvm as a tool.
I'm just trying to get a deeper understanding of Objective C.
Why do I have to cast before the call to avoid a warning? Isn't this a piece of cake for the compiler? Are there any dynamic aspects that I'm missing?
if ([a.class conformsToProtocol:#protocol(P1)])
{
[(id<P1>)a p1Message];
}
I mean, I understand it in a C/C++ point of view, but after all I'm using an Objective C compiler and I don't like casts. :)
If a is a specific type that declares itself at compile time as implementing P1 then you shouldn't need to cast.
If a is of type id then you'll need to cast only if the return type is ambiguous and you're actually using it, or if it had parameters. That'll generally mean that there are multiple method signatures for the method name p1Message so the compiler doesn't know which to expect.
If a is of some type that doesn't declare itself as implementing P1 then — unless it separately (and repetitiously) declares p1Message — you'll get a warning because you're calling a method that the object may not implement.
If I had to guess, probably a is declared as being of type id rather than id <P1> (which is more normal for, say, delegates) and you have multiple p1Messages flying around. You might also put the cast in proactively because one day you might have multiple different messages with the same name and someone else that might implement p1Message shouldn't have to know every other place in the project that somebody uses that method name.
The compiler can't induce from the conformsToProtocol: check that it is safe to call p1Message exactly because it's a dynamic runtime. You may have substituted a different implementation of conformsToProtocol: either at compile time or at runtime, meaning that it isn't safe to assume that the compiler knows what it does. That call will be dynamically dispatched just like any other.
I know that in Objective C, every object has first 4 bytes [depending upon type of processor ] as an isa pointer stored in it that tells which class it belongs to and what dispatch table to use to resolve a selector to address of a function.
What I wanted to know was , how are data members stored and accessed in these methods.
self is passed as an implicit object in each function being called.
We use setters n getters to handle data members in other member function as a good practice,
but when we directly refer to a data member in an initializer or an accesor, how are they accessed. Are they replaced by some address at compile time or something else ?
Actually afaik the memory layout is implementation specific, but http://algorithm.com.au/downloads/talks/objective-c-internals/objective-c-internals.pdf should give you a pretty good idea of the inner works of object data and object messaging.
When you use a direct member access, what basically happens is that you're fetching straight from the "struct" that is your actual object. That is, the compiler is basically just adding an offset to the address of your object/struct and reading the contents of that memory address.
Maybe I should add that this is reverse engineered from XCode and not written in any specification I can find, so depending on this behavior is most likely a bad idea. Since external access to the iVars is not allowed, the decision is basically up to the compiler and could be changed at any time.
Edit: as #FrederickCheung points out, Objective C 2.0 may have changed this behavior.
It's not as simple as a compile time offset calculation, at least not in objective C 2.0 on the 64bit OS X and iOS runtimes. These support stuff like superclasses changing their instance variable layout without breaking subclasses that were compiled against the old layout by adding a layer of indirection.
The runtime api docs describe the API one can use to set instance variables and so on but doesn't elaborate on their implementation.
What is better and why ?
What is better in such situations as the class init method and usual variables in a code ?
What is better and why ?
Explicit typing information is always better unless you just can't use it for some reason (see below).
It allows the compiler to much more stringently validate the code and will catch many errors at compile time that would otherwise cause your app to crash at runtime.
A long, long, time ago, everything in the APIs used id. This proved to be a complete pain in the butt; fragile and led to many crashes that would have been caught with specific types.
So, it was changed. (This was ~1994).
What is better in such situations as
the class init method and usual
variables in a code ?
For init, you have no choice but to use the generic (id) return type. Objective-C does not support either co-variant or contra-variant declarations, nor is there a mechanism for generalizing the declaration of init while also providing support for specific type checking.
Same goes for retain, objectAtIndex:, addObject: and many other methods that take or return one of many kinds of objects (or take 'em as arguments).
And, no, there is absolutely no performance difference whatsoever between id and, say, NSView*.
can you give an example when explicit
typing will cause a problem please?
If you wrote:
- (MyClass *) init;
And in a subclass:
- (MySubclass *) init;
You'd get compiler warnings out the wazoo most likely or you'd have to typecast out the wazoo.
On recent versions of clang (in Lion) you should actually not return id, and instead return instancetype. This is a keyword that is used in return types to specify that the type it returns is an instance of the class receiving the message. It is now the preferred return type for init methods on OS X Lion.
Explicit typing provides build-time protection, informing you of likely problems if you do things such as casting or performing operations on something that probably won't work.
Explicit typing also helps prevent non-obvious transfer of mistyped objects, something traveling through a path in your code you hadn't considered that turns out to be of an unexpected type. This kind of bug often doesn't become clear until the program has been tested a lot, more commonly after its release.
It's also helpful for future programmers (including your future self) trying to work with your code, making to more likely that they'll be able to tell at glance what an object is supposed to be. It makes code more "self-documenting" as a result.
Some things cannot have a meaningful type because no type actually applies. Other times you need to use id because you need to be able to accept any type of object. Cocoa Touch uses it, for example, when referring to the sender of a message because anything could have sent it; specifying an explicit type simply wouldn't work.
The vast majority of the time, though, an explicit type is to your advantage.
Use a type as specific as you can but not more so. Consider how you are using any particular variable, argument, or return type and set its type appropriately.
For example a UITableView's dataSource property is declared as id<UITableViewDataSource> because the table view only cares that its data source is some object which conforms to the UITableViewDataSource protocol. This allows the data source to be flexible enough for use with any specific class which implements the protocol but still allows the compiler to warn you if you attempt to assign an object which does not implement that protocol as the data source.
If you are too specific then your code becomes inflexible, accepting only specific implementations which are not strictly necessary (ie demanding a NSMutableString when you could really work with any NSString).
If you are too vague (typing everything as id for example) then you lose the ability to identify when you are sending unrecognized selectors to a particular instance and the compiler cannot identify any number of invalid statements.
For init methods follow the advice in The Objective-C Programming Language
The return type of an initializer method should be id.
The reason for this is that id gives an indication that the class is purposefully not considered—that the class is unspecified and subject to change, depending on context of invocation. For example, NSString provides a method initWithFormat:. When sent to an instance of NSMutableString (a subclass of NSString), however, the message returns an instance of NSMutableString, not NSString. (See also, though, the singleton example given in “Combining Allocation and Initialization.”)
I don't think there is a performance difference between both.
You can let id return type for init because you can cast the result of your init.
For exemple :
Toto *foo = [[Toto alloc] init];
id foo2 = [[Toto alloc] init];
Both work but you'll have to cast foo2 variable like that (Toto *)foo in order to access property or methods of your instance without creating a compiler warning. Even if it works fine...
I think some developers let id because they just pass there variable trough instance and don't use it. That kind of use allow to not import the .h
Regards,
KL94