Recently i was reading "Cocoa Design Patterns". When talking about KVC, it said "KVC check if an accessor named -<key> or -get<Key> exists first, if not, it will try instance variable named <key> or _<key>".
Can obj-c runtime check whether an instance variable exist? I think it can only be done in compile time...
Any answers are appreciated ^_^
It can indeed. The relevant documentation for this is the Objective-C Runtime Reference; specifically, class_getInstanceVariable. The part the documentation leaves out is that that function returns NULL when instances of the class have no such variable.
KVC, presumably, passes the object's class and the candidate variable names to that function, and the first name for which the runtime comes up with an Ivar is the one it uses.
Related
In my Lazarus project, I use variables of
TPortableNetworkGraphic type, which is inherited from TRasterImage. Until now, I have released them with the Free method, but I have noticed that for these types also a FreeImage method exists.
What is the difference between these two? Which one should I use, or should they be called both?
If we investigate the methods we find the following:
Method Free originates from TObject. Calling it destroys your class instance.
Method FreeImage comes from TRasterImage and is equal to SetHandle(0) method from the same class. The latter technically deals mainly with FSharedImagevariable (TSharedRasterImage class instance) and its Handle property. In other words after calling FreeImage the instance of TPortableNetworkGraphic class instance will be still "alive".
I cannot remember a single time I've needed to give the program/module name when specifying a class name in interface builder except in this case, and also the book (Big Nerd 5th ed. p162) says I wouldn't need to do it for Obj-C, but I have to for Swift, so why?
Context: I'm specifying which class the NSArrayController will be dealing with.
Swift automatically creates impromptu namespaces for you, by (for example) prefixing your Employee class with your module name. (You don't have to care about this in your code, because since you're usually referring to Employee within that module, the compiler can understand your shorthand usage of Employee.) It can be handy to be explicit about this if your module defines the same symbol as another, for example MyProject.Array vs. Swift.Array.
Why the difference between languages? Because Objective-C simply does not do this namespacing, which is why everyone prefixes their Objective-C classes with two- and three-letter codes to avoid naming collisions.
Is it possible to get an instance of java.lang.reflect.Method by using the new method reference feature of Java 8?
That way I would have a compile time check and refactoring would be also easier. Also, I wouldn't need to catch the exceptions (which shouldn't been thrown after all).
Short answer: No.
You will get a lambda of that method, not a java.lang.reflect.Method. You do not know the name of the method. Just as you can not have a reference to a "property" of a java bean.
You can have a reference to the getter or setter but that is also a lambda and you do not know the actual name.
In any case you'd have to provide the name as a String and that can't be checked by the compiler. I also tried this but failed. It simply can't be done unless you write something that checks the javacode/bytecode. But there are tools that do that.
Maybe the Criteria API could be used for that, but it depends on the requirements.
http://docs.oracle.com/javaee/6/tutorial/doc/gjitv.html
There you'd have a SingularAttribute or similar field on a "metamodel" and then the regular java compiler can check the (generic) type of it.
Xcode 4.5 and later auto-synthesizes properties, making an instance variable with the underscore prepended on the property name. But how does this work in an NSManagedObject? They want you to use KVC primitive methods in your custom setters. So what happens if you set an instance variable via the underscore ivar inside the NSManagedObject? Won't that screw things up since it would bypass the KVC methods? Or is it safely doing this behind the scenes?
If you access the underscore instance variable directly, you are bypassing the work that NSManagedObject does for you. You should use the get and set accessor methods that NSManagedObject auto-generates for your attributes.
Apple's documentation states
When you access or modify properties of a managed object, you should
use these [accessor] methods directly.
You can implement your own accessor methods if required, but in that case, you have to do additional work beyond changing the value of the instance variable:
You must ensure that you invoke the relevant access and change
notification methods (willAccessValueForKey:, didAccessValueForKey:,
willChangeValueForKey:, didChangeValueForKey:,
willChangeValueForKey:withSetMutation:usingObjects:, and
didChangeValueForKey:withSetMutation:usingObjects:).
This should illustrate that you can't get the correct behavior simply by modifying the instance variable directly.
Note that unlike ordinary properties, NSManagedObject properties are not synthesized at compile time (hence the use of #dynamic for the implementation). Since compile-time synthesis isn't used, there are no synthesized instance variables available for you to set.
Instead, instances of NSManagedObject have a private internal instance of something similar to an NSMutableDictionary to store their state. The dynamically generated property accessors are wrappers for calls to KVC-like methods that access the private storage.
I'm still new to Cocoa and don't know much about memory management. I read up on Apple's documentation but I'm still confused. My question is if I set the value of a variable in a - (void)dowhatever when dowhatever ends, will the contents of the variable be erased? If so is there a method (without writing to a file) that I can use to retain the variable contents?
Thanks for any help
My question is if I set the value of a variable in a - (void)dowhatever when the void ends, …
void is a type. It has no beginning and no end.
Specifically, it's the return type of the dowhatever method. If dowhatever returned a value, the type of that return value would be where you have void; it would say, for example, - (NSUInteger) doWhatever. Having void there means that the method does not return a value.
See also the Objective-C 2.0 Programming Language document.
… will the contents of the variable be erased?
If it's a local variable, then the variable will cease to exist when the method returns.
An instance variable exists as long as the instance (object) that the variable is a part of exists—that is, until the instance is deallocated.
Instance variables are also covered in the Objective-C documentation.
If so is there a method (without writing to a file) that I can use to retain the variable contents?
If you simply need to return the object to your caller, retain it and autorelease it. See the Memory Management Programming Guide for Cocoa for more info.
If that's not what you're doing, then the question becomes why you need the object to stay alive.
Think in terms of objects: An object may own certain other objects, and has an instance variable for every object it owns*. As long as you have your ownerships straight and uphold them in code, objects' lifetimes just work.
If object A needs another object B, then A should own B. This ownership isn't exclusive; it can co-own B. But it needs to at least co-own B; B will remain alive as long as it has at least one owner.
That's also covered in the Memory Management Guide. For other examples of relationships between objects, you should flip through the Cocoa Fundamentals Guide, particularly the chapter on Cocoa's design patterns, and you may want to look through sample code to see those patterns demonstrated in practice.
*It can also have instance variables for objects it doesn't own, such as delegates. You can have an instance variable for an object you don't own, but if you do own it, you should have an instance variable for it.