How to override the NSObject methods without inheriting from NSObject in swift - ios

I actually want to know how to access the encodeWithCoder, init etc methods from the NSObject or any other class without inheriting from NSObject class.
Because I read that if we inherit from the NSObject class then it has performance issues in Swift or similar performance to the Objective - C.
So please let me know how to do it.

You want to override a super class method from a class that doesn't inherit from that super class, this doesn't make sense. If you need to use encodeWithCoder method, you'll have to extend NSObject class or any other class that conforms to NSCoding protocol. Otherwise you can create your custom class that conforms to NSCoding protocol and implement the same functionality in encodeWithCoder method.
From Apple documentation
Any class that does not inherit from another class is known as a base class.
NOTE
Swift classes do not inherit from a universal base class. Classes you
define without specifying a superclass automatically become base
classes for you to build upon.

Related

Cannot adopt a swift class to an objective C protocol of type X <NSObject>

I am very new to Swift and so I may phrase things weirdly here. Apologies!
I've got the following (simplified) protocol in Objective C:
#protocol OtherProtocol <NSObject>
#optional
...
#end
I would like to create a class in Swift (4.2) that adheres to this protocol, so I defined my class like:
class MyClass : OtherProtocol {
}
Naturally, XCode will complain because my class doesn't have the correct methods.
It looks like I need to implement a bunch of NSObject methods in addition to those defined in OtherProtocol. When XCode adds in the missing method stubs from NSObject, there's one in particular giving issues:
func `self`() -> Self {
...
}
The problem with this method is Method cannot be an implementation of an #objc requirement because its result type cannot be represented in Objective-C.
I'd like the quickest way out of this, as I won't end up using any of those standard NSObject functions anyways. Any thoughts?
Actually, there is no need to implement NSObject's methods.
To be able to subclass/inherit from Objective-C classes/protocols you just need to inherit from NSObject. This is to make sure that your Swift class can be used in Objective-C environment as well. Also, Swift structs can't adopt Objective-C protocols, as there is no such type in Obj-C
This should work
class MyClass: NSObject, OtherProtocol {
}

How can I access to the methods of a class when there is multiple inheritance on Swift?

I have a class that inherits from another class.
class Profile: UserData{
}
And at the same time UserData inherits from UIViewController.
The problem comes because I need that Profile class also inherits from UITabBarController and I need to access to the methods of UserData class from Profile class.
What I have tried is:
class Profile: UITabBarController{
override func viewDidLoad() {
super.viewDidLoad()
UserData().doStuff()
}
}
but this does not work for me because I need to inherit the full class (the method only works when I use class Profile: UserData).
I know about protocols and I tried to inherit on the protocol the class UserData but it is also not allowed. I also have tried copying the methods of UserData class on that protocol but it gives to me the following error:
Protocol methods may not have bodies
As, by the moment, it is impossible to do multiple inheritance, is it possible to make a workaround to use all the methods of UserData (as if I have inherited it) on Profile class which inherits at the same time from UITabBarController?
Thanks in advance!
You need to use Protocol and delegates - apple doc. As you said that you tried protocol then you must have done some mistake in implementation. Otherwise this can be handle by protocol and delegates.
Refer apple documentation as i have shared in above paragraph.
You profile class should be delegate of your userdata class. and then it can access it's methods.
You car refer Quick Guide to Swift Delegates also!

Having coming code in class for two class that have different base class

I have
classA : MPMoviePlayerViewController
classB : UIViewController
Both classA and classB have a lot of same code that is duplicated. Which I want to put in one class but as the classes inherit from two different classes it is not possible to make a common base class. Any way to solve this problem
Thanks in advance!
You can create category on UIViewController, since both class ultimately inherits from them. As long as you don't need to add stored variable that fine (category can do that too, but it's a bit trickier).
Or you can make both class conforming a protocol and use a third class that would do the common stuff, and you inject the classA or classB instance when needed.

Class Extension vs Primary Interface vs Category

I am fairly new to realm of iOS. Coming from Java and Android background i am facing few challenges while learning objective C.
My question: I understand how the above three are different from each other but I fail to understand their use cases in practice.
Do we need a Class Extension for every class with private functions? What is the use of Category, when we can extend a Cocoa/Cocoa-touch class in interface and add custom functions? Please do provide some example from your experience.
Categories are a way to split a single class definition into multiple files.A category can be declared for any class, even if you don't have the original implementation source code.At runtime, there's no difference between a method added by a category and one that is implemented by the original class.
example for categories:
NSString+UrlString.h
#import <UIKit/UIKit.h>
#interface NSString(Additions)
+(void)urlMethod;
#end
NSString+UrlString.m//implmentation
#import "NSString+Additions.h"
#implementation NSString (Additions)
+(void)urlMethod
{
}
#end
The primary interface for a class is used to define the way that other classes are expected to interact with it. In other words, it’s the public interface to the class.
Class extensions are often used to extend the public interface with additional private methods or properties for use within the implementation of the class itself.
Class extensions are used to declare private methods in objective C
For example, to define a property as readonly in the interface, but as readwrite in a class extension declared above the implementation, in order that the internal methods of the class can change the property value directly.
The methods declared by a class extension are implemented in the implementation block for the original class, so you can't, for example, declare a class extension on a framework class, such as a Cocoa or Cocoa Touch class like NSString..
The syntax to declare a extension uses the #interface keyword, just like a standard Objective-C
#interface ClassName ()
#end
you may find that you wish to extend an existing class by adding behavior that is useful only in certain situations. Please refer this
Category is adding methods to a class in the runtime. As far as the runtime is concerned, the methods that are implemented in a class extension, ARE the methods that are available for the class itself. Category in Objective-C is a fancy name for Monkey Patching in other programming languages like C#. You can read about it here.
With that said, you can create a category for UIColor with some method if you want every UIColor to have that behaviour throughout that module. This isn't the case with subclassing. Only the subclassed (theoretically speaking) UIColor object will get those behaviour since there is a distinct difference in the type of the object.
Example:
UIColor has built in methods that give you different colors; you can call UIColor.greenColor() to get the green color; UIColor.blackColor() to get black color and so on...
Suppose you want your own to be called in a similar fashion, you create a category (example in swift) like so
extension UIColor {
static func yourColor() -> UIColor {
return UIColor(red:220/225,green:222/225,blue:223/225)
}
}
This way, it is valid for you to call UIColor.yourColor(). Every UIColor that you would use has this method available. Convenient than subclassing, isn't it?
Creating a subclass has polymorphic implications; categories don't. You subclass only when you need refinement of an existing class and treat it both as a parent and the child when required. As a Java developer you would know when it makes sense to subclass.
An extension is best for private methods which you would like to declare in your .m file. Think of extension as a category private to the .m file.
Class Extesions: If you mean by Extension Methods like in .Net, then it called as Category in Objective-C.
Categories: These are nothing but the Extension Methods, it allows to add methods in existing classes from iOS SDK (like NSString, NSURL, etc.)
For more details: Apple Doc: Category
Primary Interface: Writing a class (Interface in terms of Objective-C) definition inside its implementation file called primary interface.
//ClassName.mm #interface ClassName() {
Declarations;
}
- Methods;
+ Methods;
#end
#implementation ClassName
#end
So, Categories are also one type of primary interfaces.

Why should I conform Custom Protocol to NSObject?

Any object which assign to Custom protocol reference, is always be Confirm by NSObject Protocol directly or By superclasses. So Why should I do this?
I really don't know, whether I got you right.
If you meant that a custom protocol always confirms to the NSObject protocol, there is a pretty simply reason for it. It is a little bit weird:
If you type a reference to id the compiler accepts every message to that he has seen while compiling the translation unit ("class", "module", the file you compile).
If you type an object reference to id<protocol>, the compiler only accepts messages that are declared inside the protocol. But this is never enough!
#protocol MyProtocol
#optional
- (void)doItOrNot;
#end
The only message you can send is -doItOrNot. So the compilation of such code will fail:
id<MyProtocol> ref = …;
if ([ref respondsToSelector:#selector(doItOrNot)]) // <- Error -respondsToSelector is not declared in the protocol.
…
By adding the NSObject protocol to your protocol you import some fundamental declarations. (Including MM for MRC.)
It sounds like you might be trying to ask about using the NSObject protocol, since every class has NSObject as an ancestor.
The answer, then, is that it's not true that every object is derived from NSObject. Most are, but NSProxy is an example of one that's not. The methods in the NSObject protocol are what any instance of the NSObject class is expected to implement, so by implementing the NSObject protocol, NSProxy is able to provide the same behaviors that any class derived from NSObject (class) has.
For example, you can use methods like -isEqual and -hash with instances of NSProxy.
If you're creating a subclass of the NSObject class, there's no need to declare that your class implements the NSObject protocol because the NSObject class already does that for you.
Also, just as you can declare that a class adopts a protocol with:
#interface MyClass <SomeProtocol>
you can also declare that a protocol adopts another protocol:
#interface MyProtocol <SomeProtocol>
Since, as explained above, not every class is a subclass of NSObject (the class), having MyProtocol adopt NSObject (the protocol) guarantees that you can call NSObject methods. If you want to specify that a method takes any kind of object that adopts YourProtocol, you can do that by specifying the type as id<YourProtocol>. However, if YourProtocol isn't declared to adopt the NSObject protocol, you can't be certain that it's safe to call NSObject methods like -isEqual, and you can't even check that it's safe using -respondsToSelector: or -isKindOfClass: because those methods themselves are part of the NSObject protocol.
Cocoa defines an NSObject protocol that mirrors the NSObject class and instance methods. By declaring that your custom protocol implements the NSObject protocol, you give the compiler a hint that all of the NSObject methods will be implemented by an instance that implements your custom protocol.
If you don't include the NSObject protocol, you'll get warnings when you try to call any of the NSObject methods for instance respondsToSelector: on the object.
You don't have to. But the problem is that a lot of the core functionality of NSObject — indeed, all the core functionality necessary for NSObject to function as a base class — is declared in the NSObject protocol. (This strange architecture is so that both NSObject and NSProxy can be base classes: they both adopt the NSObject protocol.)
Now, if you declare an object's type as id<MyDelegate>, the only messages you can send that object are MyDelegate messages. That's fine, usually; but what if you want to send it, say, the respondsToSelector: message? That method is declared in the NSObject protocol, not in the MyDelegate protocol. So the compiler will stop you.
There are two solutions. Either declare the object's type as NSObject<MyDelegate>, or make MyDelegate adopt the NSObject protocol. Either way, the compiler is now satisfied, and you can send this object the respondsToSelector: message.

Resources