Objective-C equivalent for Java anonymous inner class [duplicate] - ios

I often use this statement for extending class without needs of writing a whole separate file. Supposing ClassFromFramework is a class being part of a framework included in library.
public ClassFromFramework {
public String myMethod() {
// operations
}
//lot of other methods....
}
Then in my class I could do the following:
import com.framework.ClassFromFramework;
public MyClass {
public void method() {
ClassFromFramework m = new ClassFromFramework() {
#Override
public String myMethod() {
// do operations...
}
}
m.myMethod();
}
}
I wonder if I can achieve the same with Objective-c without declaring a new combination .h .m files and import in my using class.

You can make a new subclass, and override methods, but all new classes must be in their own .h & .m files. That's how Obj-C operates. In this case, it would make sense to have the additional files.
You can also call the parent method with the word super. This is done all the time when subclassing a ViewController, such as in viewDidLoad.

Related

In Dart, it is not possible to override a static method. but i can't understand output of this code

class Student {
static void getDetails() {
print('Get details method of Student class');
}
}
class DartStudent extends Student {
static void getDetails() {
print('Get details method of DartStudent class');
}
}
void main() {
DartStudent.getDetails();
}
Output : Get details method of DartStudent class
Expected : Error. static method cannot be overriden.. or something wrong..
what's wrong with me?
getDetails() in DartStudent class is not overriding parent class's method?
You can't override static methods.
The two static methods you declared there are in fact two different static methods, not the same, overriden one.
Answer for a different question, but related:
Dart doesn't inherit static methods to derived classes. So it makes no sense to create abstract static methods (without implementation).
Also check out Why shouldn't static methods be able to be overrideable?. It provides a thorough explanation of why static methods should not be overrideable in general.

How to use a generic class without the type argument in Swift?

I want to encapsulate a generic object in another class without setting the generic type argument. I created a base Animal<T> class and defined other subclasses from it. Example:
public class Animal<T: YummyObject> {
// Code
}
public class Dog: Animal<Bark> {
// Code
}
public class Cat: Animal<Meow> {
// Code
}
and defined an Animal property, without the type argument, in the UITableView extension bellow:
extension UITableView {
private static var animal: Animal!
func addAnimal(animal: Animal) {
UITableView.animal = animal
}
}
but I get the following compile error when doing so:
Reference to generic type Animal requires arguments in <...>.
This seems to work fine in Java. How can I accomplish the same thing in Swift as well?
Swift doesn’t yet support wildcard-style generics like Java does (i.e., Animal<?>). As such, a common pattern is to define a type-erased superclass, protocol (or wrapper) to enable such usage instead. For instance:
public class AnyAnimal {
/* non-generic methods */
}
and then use it as your superclass:
public class Animal<T: YummyObject>: AnyAnimal {
...
}
Finally, use AnyAnimal in your non-generic code instead:
private static var animal: AnyAnimal!
Examples in the Swift Standard Library. For a practical example, see the KeyPath, PartialKeyPath, and AnyKeyPath classes hierarchy. They follow the same pattern I outlined above. The Collections framework provides even further type-erasing examples, but using wrappers instead.

Using Typhoon, create instance of a subclass of a class which has dependencies

I am using Typhoon for dependencies injection in Swift for iOS.
I have created an assembly to inject dependencies in a class called BaseRequest like this:
public class NetworkAssembly: TyphoonAssembly {
public dynamic func baseRequest() -> AnyObject {
return TyphoonDefinition.withClass(BaseRequest.self){
(definition) in
definition.useInitializer("initWithRetryCount:userUmbrella:networkQueueManager:"){
(initializer) in
initializer.injectParameterWith((TyphoonConfig("network.request.retry.count") as! NSNumber).integerValue)
initializer.injectParameterWith(self.coreComponents.userUmbrella())
initializer.injectParameterWith(self.networkQueueManager())
}
}
}
}
Now, I am trying to create a subclass of BaseRequest with a factory method like this:
class DownloadLibrariesRequest: BaseRequest {
var libraries:Array<String> = []
class func downloadLibraries(libraries:Array<String>)->Void{
let request: DownloadLibrariesRequest = DownloadLibrariesRequest(.....)
request.libraries = libraries
}
}
I need to be able to create an instance of DownloadLibrariesRequest and call the NetworkAssembly for BaseRequest since I need to use another init in the subclasses.
Also, I need to mention that I will have around 50 such subclasses, so creating assemblies for all of them doesn't sound too great at the moment.
To create a definition with shared configuration, in order to avoid repetition, use the parent feature.

Dart: how to reference methods of classes

While writing library documentation I need to be able to reference (i.e. link to) methods from other classes (in the same library) but with the same method name (i.e. reference the delegating method from the docs of the one that is doing the work).
I have tried ClassName.method (does not work) and directly using the method (references the same class method).
Any ideas?
Thanks.
/// [B.someMethod] ..
/// [someMethod] ..
class A {
void someMethod() {
}
}
/// [A.someMethod]
/// [someMethod]
class B {
void someMethod() {
}
}
/// [A.someMethod]
void main() {
new A().someMethod();
}
All references in the doc comments work for me in this example, but sometimes DartEditor shows them only as links after a delay or after some other edits.
Its a docgen issue/bug - can be monitored here: https://code.google.com/p/dart/issues/detail?id=22144

"initialize" class method for classes in Swift?

I'm looking for behavior similar to Objective-C's +(void)initialize class method, in that the method is called once when the class is initialized, and never again thereafter.
A simple class init () {} in a class closure would be really sleek! And obviously when we get to use "class vars" instead of "static vars in a struct closure", this will all match really well!
If you have an Objective-C class, it's easiest to just override +initialize. However, make sure subclasses of your class also override +initialize or else your class's +initialize may get called more than once! If you want, you can use dispatch_once() (mentioned below) to safeguard against multiple calls.
class MyView : UIView {
override class func initialize () {
// Do stuff
}
}
If you have a Swift class, the best you can get is dispatch_once() inside the init() statement.
private var once = dispatch_once_t()
class MyObject {
init () {
dispatch_once(&once) {
// Do stuff
}
}
}
This solution differs from +initialize (which is called the first time an Objective-C class is messaged) and thus isn't a true answer to the question. But it works good enough, IMO.
There is no type initializer in Swift.
“Unlike stored instance properties, you must always give stored type properties a default value. This is because the type itself does not have an initializer that can assign a value to a stored type property at initialization time.”
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks.
You could use a type property which default value is a closure. So the code in the closure would be executed when the type property (or class variable) is set.
class FirstClass {
class var someProperty = {
// you can init the class member with anything you like or perform any code
return SomeType
}()
}
But class stored properties not yet supported (tested in Xcode 8).
One answer is to use static, it is the same as class final.
Good link for that is
Setting a Default Property Value with a Closure or Function
Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks.
Code example:
class FirstClass {
static let someProperty = {
() -> [Bool] in
var temporaryBoard = [Bool]()
var isBlack = false
for i in 1...8 {
for j in 1...8 {
temporaryBoard.append(isBlack)
isBlack = !isBlack
}
isBlack = !isBlack
}
print("setting default property value with a closure")
return temporaryBoard
}()
}
print("start")
FirstClass.someProperty
Prints
start
setting default property value with a closure
So it is lazy evaluated.
For #objc classes, class func initialize() definitely works, since +initialize is implemented by the Objective-C runtime. But for "native" Swift classes, you'll have to see the other answers.
You can use stored type properties instead of initialize method.
class SomeClass: {
private static let initializer: Void = {
//some initialization
}()
}
But since stored types properties are actually lazily initialized on their first access, you will need refer them somewhere. You can do this with ordinary stored property:
class SomeClass: {
private static let initializer: Void = {
//some initialization
}()
private let initializer: Void = SomeClass.initializer
}
#aleclarson nailed it, but as of recent Swift 4 you cannot directly override initialize. You still can achieve it with Objective-C and categories for classes inheriting from NSObject with a class / static swiftyInitialize method, which gets invoked from Objective-C in MyClass.m, which you include in compile sources alongside MyClass.swift:
# MyView.swift
import Foundation
public class MyView: UIView
{
#objc public static func swiftyInitialize() {
Swift.print("Rock 'n' roll!")
}
}
# MyView.m
#import "MyProject-Swift.h"
#implementation MyView (private)
+ (void)initialize { [self swiftyInitialize]; }
#end
If your class cannot inherit from NSObject and using +load instead of +initialize is a suitable fit, you can do something like this:
# MyClass.swift
import Foundation
public class MyClass
{
public static func load() {
Swift.print("Rock 'n' roll!")
}
}
public class MyClassObjC: NSObject
{
#objc public static func swiftyLoad() {
MyClass.load()
}
}
# MyClass.m
#import "MyProject-Swift.h"
#implementation MyClassObjC (private)
+ (void)load { [self swiftyLoad]; }
#end
There are couple of gotchas, especially when using this approach in static libraries, check out the complete post on Medium for details! ✌️
I can't find any valid use case to have something like +[initialize] in Swift. Maybe this explains way it does not exist
Why do we need +[initialize] in ObjC?
To initialize some global variable
static NSArray *array;
+ (void)initialize {
array = #[1,2,3];
}
which in Swift
struct Foo {
static let array = [1,2,3]
}
To do some hack
+ (void)initialize {
swizzle_methodImplementation()
}
which is not supported by Swift (I can't figure out how to do it for pure Swift class/struct/enum)

Resources