I'm wanting to write a base class that, when derived from, contains code stubs like it does when you descend from a UITableViewController. It automatically stubs in code, #warnings, and comments in the descended class.
For example: (if my class has the equivalent of an abstract method that they need to implement then it should appear in the new class automatically.)
-(int)thisNeedsToBeImplemented{
``#warning Incomplete implementation, return the int value needed.
}
I haven't been able to find a relevant article.
Related
I'm working on a framework.
The library is written in Swift and I notice that when a class inherits from NSObject or conforms to NSObjectProtocol, its declaration can be found in *.framework/Headers/*-Swift.h.
This class is available outside of the module in Objective-C code, so it became public.
Why does it happen if the access level is internal?
Internal Swift classes need to be available to the Objective-C code of that framework, however the only way Objective-C code can access the Swift classes is by importing the -Swift.h header file.
Now, how can a Swift class be visible to Objective-C: it either needs to inherit NSObject, or conform to NSObjectProtocol. If any of these two conditions is fulfilled, and the class declaration is not decorated with #nonobjc/private/fileprivate, then it will be exported to Objective-C via the -Swift.h module header.
This is why any Swift classes that are exportable to Objective-C will automatically be present in the discussed header file. It's an (unfortunate) coincidence that for frameworks this results in the class being publicly available (due to the fact that any Objective-C declarations that appear in a header are public).
Now, if you want your class to not end up in the -Swift.h header file, but still want to keep the NSObject(Protocol) inheritance/conformance, a workaround would be to make your class generic, thus prohibiting its exposure to Objective-C. Note that this will also prevent the class from being available to Objective-C code in the same framework.
// the generic argument doesn't matter, it's only used to make the class
// Swift-only
class MyClass<T>: NSObject { }
The caveat would be that every time the class is used, you will need to specify a value for the generic argument. This can be avoided by adding an intermediary base class:
// just a class that inherits NSObject, but is not exported in the -Swift header
class Empty<T>: NSObject { }
class MyClass: Empty<String> { }
Is it possible to initialize a property in a category?
For example, if I have a mutable array property called nameList in a class. Is it possible to have a category created for this class to add an object to the array property before any of the category method is called?
If I understand you correctly, and others are interpreting your question differently, what you have is:
A class with a property
A category on that class
And you want to call a particular method automatically before any category method is called on a given instance, that method would "initialise" the category methods by modifying the property.
In other words you want the equivalent of a subclass with its init method, but using a category.
If my understanding is correct then the answer is no, there is no such thing as a category initializer. So redesign your model not to require it, which may be to just use a subclass - as that provides the behaviour you are after.
The long answer is you could have all the category methods perform a check, say by examining the property you intend to change to see if you have. If examining the property won't determine if an object has been "category initialized" then you might use an associated object (look in Apple's runtime documentation), or some other method, to record that fact.
HTH
Addendum: An even longer/more complex solution...
GCC & Clang both support a function (not method) attribute constructor which marks a function to be called at load time, the function takes no parameters and returns nothing. So for example, assume you have a class Something and a category More, then in the category implementation file, typically called Something+More.m, you can write:
__attribute__((constructor)) static void initializeSomethingMore(void)
{
// do stuff
}
(The static stops the symbol initializeSomethingMore being globally visible, you neither want to pollute the global name space or have accidental calls to this function - so you hide it.)
This function will be called automatically, much like a the standard class + (void) initialize method. What you can then do using the Objective-C runtime functions is replace the designated initializer instance methods of the class Something with your own implementations. These should first call the original implementation and then an initialize your category before returning the object. In outline you define a method like:
- (id) categoryVersionOfInit
{
self = [self categoryVersionOfInit]; // NOT a mistake, see text!
if (self)
{
// init category
}
return self;
}
and then in initializeSomethingMore switch the implementations of init and categoryVersionOfInit - so any call of init on an instance of Something actually calls categoryVersionOfInit. Now you see the reason for the apparently self-recursive call in categoryVersionOfInit - by the time it is called the implementations have been switched so the call invokes the original implementation of init... (If you're crosseyed at this point just draw a picture!)
Using this technique you can "inject" category initialization code into a class. Note that the exact point at which your initializeSomethingMore function is called is not defined, so for example you cannot assume it will be called before or after any methods your target class uses for initialization (+ initialize, + load or its own constructor functions).
Sure, it possible through objc/runtime and objc_getAssociatedObject/objc_setAssociatedObject
check this answer
No it's not possible in objective c.Category is the way to add only method to an existing class you can not add properties in to this.
Read this
Why can't I #synthesize accessors in a category?
I'm following a tutorial on how to create a popover in Iphone here
what is (overrides) this code:
#interface UIPopoverController (overrides)
+ (BOOL)_popoversDisabled;
#end
#implementation UIPopoverController (overrides)
+ (BOOL)_popoversDisabled
{
return NO;
}
#end
This is an objective-C category. A category is a way of providing extra methods on a class, and they're useful in the following situations:
Extending a library class with domain-specific functionality. ie providing some extra features that will be useful for your application. This works whether or not you have the source-code for that class. For example, you could implement an [NSString asCreditCard] method or [UIColor applicationThemeColor].
Categories are also invaluable for grouping related functionality in a complex class.
Objective-C categories have the restriction that you cannot define additional ivars, and thus ivar-backed properties, on a category, although you can easily work around this using associative references - a run-time feature allowing you to link an object to a given class.
Associative References
To 'fake' a property or ivar on a category class use the following:
Define a 'key' to reference the associated property.
static char const* const carNamekey = "com.myObject.aKey";
The key doesn't necessarily have to have a value, since its the memory address of the object that is actually used.
Now, Implement the properties:
- (void) setCar:(Car*)car
{
objc_setAssociatedObject(self, &carNamekey, car, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (Car*) car
{
return objc_getAssociatedObject(self, &carNamekey);
}
If you wish you can add an #property declaration on the interface definition for the category, as an invitation to users of the class to use property-style (ie class.property = xxx) syntax.
Class Extensions
Another feature that is very similar to Objective-C categories is the class extension. A class extension is defined in the implementation block for a class like so:
#interface MyClass()
Some people refer to these as 'empty categories', but this is not quite correct. Unlike a category, a class extension will allow you to define additional properties and ivars on a class, without using associative references. This is useful for making a readonly property, internally writable, and things like that.
There - now you probably know more about categories than a lot of folks :)
Jasper Blues' answer explains categories nicely, so I'll just add that you should avoid using categories to override methods in the class to which you're adding the category. The reason is that the order in which categories are added to a class is undefined, so you can't know for certain whether the class will get your version of a method or one defined in another category. If you need to override methods in a class, create a subclass and put your overrides there.
However, people sometimes use categories to organize the methods in a class definition. If that's the case here, the method(s) in the overrides category are probably meant to override methods in the superclass, which is fine.
I'm using a Objective-C framework for game development called Cocos2d-iphone.
This is how I create a button-graphic in the game:
CCMenuItemImage *battle;
battle = [CCMenuItemImage itemFromNormalImage:#"BattleFightOption1.png" selectedImage:#"BattleFightOption2.png"
target:self selector:#selector(battleFightOption)];
Basically, when the user clicks the button, method battleFightOption runs.
But I wonder, I never did define battleFightOption in the interface.. so, my question is: when is it necessary to define a method in the interface, and when is it not?
In short, every method that is meant to be used from outside the class must be declared in the interface; methods that are internal to the class implementation are omitted. The latter are typically declared in a class extension.
When you use a selector like #selector(methodName:), methodName: is called dynamically at runtime. The compiler doesn't have to know where it is, and doesn't check that the method exists when you compile.
However, it is still a good idea to declare it privately, which is generally done by putting an unnamed category at the top of the .m file (generally referred to as a class extension):
#import "Class.h"
#interface Class ()
- (void)privateMethod;
#end
#implementation Class
...
Anything that you intend to be public, called outside of the class, should be defined in the interface. If you are going to only use #selector(battleFightOption) you really do not need to define the method anywhere but I would recommend that you add a definition in the class extension just as you would any other private method.
I know of a couple of rules regarding Objective-C categories:
Category methods should not override existing methods (class or instance)
Two different categories implementing the same method for the same class will result in undefined behavior
I would like to know what happens when I override one of my own category methods in the same category. For example:
#interface NSView (MyExtensions)
- (void)foo; // NSView category implementation
#end
#interface MyClass : NSView
{ }
#end
#interface MyClass (MyExtensions)
- (void)foo; // MyClass category implementation
#end
With these interfaces defined, which method will be executed when I run the following code?
MyClass * instance = [[MyClass alloc] initWith...];
[instance foo];
[instance release];
Note: With my compiler, the MyClass implementation takes precedence, but I'm not sure if that is guaranteed to occur, or simply one specific flavor of undefined behavior.
To extend on drawnonward answer:
It's matter of hierarchy. Categories are really just a means of organizing source files. When compiled, all the methods of a class, including the ones defined in any category, end up in the same file.
Anything you could do in a regular class interface you can do in a category and anything you shouldn't do in a regular class interface you shouldn't do in a category.
So:
Category methods should not override
existing methods (class or instance)
You can use methods defined in the regular class interface to override inherited methods so you can override inherited methods in a category.
However, you would never try to have to two identical method definitions in the same ordinary interface so you should never have a method in a category that has the same name as a method in either the ordinary interface or another category on the same class. Since all the method definitions end up in the same compiled file, they would obviously collide.
Two different categories implementing
the same method results in undefined
behavior
That should be rewritten to say "Two different categories implementing the same method for the same class results in undefined behavior." Again, because all the methods for any one class end up in the same file, having two methods in the same class would obviously cause weirdness.
You can use categories to provide methods that override superclass methods because a class and its superclass are two distinct classes.
If your ever confused about whether a category will cause problem just ask yourself this: "Would the methods in the category work if I copied and pasted them all into the class' .h/.m files?" If the answer is "yes" then you're in the clear. If "no", then you've got problems.
Each method of each class has an implementation. A category adds or replaces a method for a specific class. That means the behavior you are seeing, where MyClass has one foo and NSView has another foo, is well defined. Any instance of MyClass will have a different foo than any instance of NSView that is not a MyClass, just as if foo had been defined in the main implementation and not a category. You should even be able to call [super foo] from MyClass to access the foo defined for NSView.