On a lot of NSURLConnection examples I see the following lines:
NSURLConnection *theConnection = [[NSURLConnection alloc]initWithRequest:theRequest delegate:self];
if(theConnection)
{
webData = [[NSMutableData data]retain];
}
else
...
I wonder - what is this supposed to do? and why does it work? I thought that data is an accessor method, and since your not calling it on an instanciated object, it will return nil, and by retaining it you actually do nothing.
This is the way I have seen to get data on connections like this:
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:url] delegate:self startImmediately:YES];
if( connection )
{
while (!finished) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
}
finished is an ivar that gets set to YES on connectionDidFinishLoading:
Can anyone clear this up for me? Which should be used and what's the difference?
[NSMutableData data] is not an accessor but a so-called class method. You probably know [NSMutableData alloc], that too is a class method and means it is tied to the class but not an instance. The typical way to denote that a method is a class method is by prefixing it with a plus: +[NSMutableData data].
In this case, the method is inherited from the NSData class (but does return an NSMutableData instance, since you're calling it on that class).
An implementation might look like this:
#interface NSMutableData
+ (id)data
{
return [[[self alloc] init] autorelease];
}
#end
Note that self in this case is the NSMutableData class.
In other languages like C++, C# and Java (AFAIK) these would be methods that you specify with the static keyword.
Related
I am attempting to implement a solution from How to set canBecomeKeyWindow? Into my native C application using Objective-C runtime (The app is already written with objective C Runtime). Is there a way to create a subclass purely in Objective-C Runtime?
Right now I just create NSWindow object but need to be able to create my own so I can override the function specified in that question.
objc_msgSend((id)objc_getClass("NSWindow"), sel_registerName("alloc"));
The signature of can_become_key_window_true is slightly incorrect. According to the documentation (https://developer.apple.com/documentation/objectivec/objective-c_runtime/imp?language=objc) the function should have at least two arguments: "self" and "_cmd". So the signature should be like:
static bool can_become_key_window_true(__unused id _self, __unused SEL _cmd) {
return true;
}
You could also use #encode to construct the type encoding for the function.
char encoding[10]; // should be enough
snprintf(encoding, 10, "%s%s%s", #encode(BOOL), #encode(id), #encode(SEL));
... or you could get a method from UIWindow and get its type encoding like:
Method m = class_getInstanceMethod(objc_lookUpClass("UIWindow"), sel_getUid("canBecomeKeyWindow"));
const char *encoding = method_getTypeEncoding(m);
And as you might have noticed you could use sel_getUid() instead of sel_registerName as you expect this selector to be already registered by this time (because you are about to override an existing method).
To allocate a new instance you could use
window = class_createInstance(__UIWindow);
Figured it out after a lot of code searching:
// Subclass NSWindow with overridden function
Class __NSWindow =
objc_allocateClassPair(objc_getClass("NSWindow"), "__NSWindow", 0);
class_addMethod(__NSWindow,
sel_registerName("canBecomeKeyWindow"),
(IMP)can_become_key_window_true, "B#:");
objc_registerClassPair(__NSWindow);
// Allocate a new __NSWindow
window = objc_msgSend((id)__NSWindow, sel_registerName("alloc"));
And then can_become_key_window_true is defined as:
static bool can_become_key_window_true() {
return true;
}
I use objc_allocateClassPair to subclass the object and return a Class of that object. Then I use class_addMethod to override the method canBecomeKeyWindow. And finally use objc_registerClassPair to register my new class before using it as I would a normal NSWindow.
I created some classes with Ruby's C API. I want to create a function whose behavior will change depending on the class of the Ruby object.
I tried to use is_a? from Ruby, however, I don't think it's the good way to do this. I checked "Creating Extension Libraries for Ruby" without success. The only direct way to check classes is with the default types.
I have my class "Klass" already created:
VALUE rb_cKlass = rb_define_class("Klass", rb_cObject);
And how I wanted to check if the class is the good one:
VALUE my_function(VALUE self, VALUE my_argument) {
if(rb_check_class(my_argument), rb_cKlass)) {
// do something if my_argument is an instance of Klass
} else {
return Qnil;
}
}
Is there a way to do this?
I came across this recently, and used the RBASIC_CLASS macro, but was getting segfaults in certain scenarios for some unexplained reason.
After scanning through ruby.h, I found the CLASS_OF macro, which returns the class as VALUE of a given object.
VALUE obj = INT2NUM(10);
VALUE klass = CLASS_OF(obj); // rb_cInteger
Using Ruby 2.5
Every ruby object is internally represented by RObject struct (I will copy the source here for the sake of future readers):
struct RObject {
struct RBasic basic;
union {
struct {
uint32_t numiv;
VALUE *ivptr;
void *iv_index_tbl; /* shortcut for RCLASS_IV_INDEX_TBL(rb_obj_class(obj)) */
} heap;
VALUE ary[ROBJECT_EMBED_LEN_MAX];
} as;
};
The very first member, RBasic, defines the class:
struct RBasic {
VALUE flags;
const VALUE klass;
}
To get an access to RBasic metadata of anything, one might use RBASIC macro:
RBASIC(my_argument)
To get the class directly, one might use RBASIC_CLASS macro:
RBASIC_CLASS(my_argument)
If you want to stay close to the is_a? Ruby fashion (i.e. check if any of the ancestors is the expected class), you could directly use the C implementation of is_a?, rb_obj_is_kind_of:
rb_obj_is_kind_of(my_argument, rb_cKlass) // Qtrue OR Qfalse
And since Qfalse == 0, you can just use that method as a condition:
VALUE my_function(VALUE self, VALUE my_argument) {
if(rb_obj_is_kind_of(my_argument, rb_cKlass)) {
// do something if my_argument is an instance of Klass
} else {
return Qnil;
}
}
To find this method, just check Object#is_a? documentation and click to toggle source, you'll see the C implementation if it is a C function (hence this will work for most of the standard lib).
I am really new to Xcode. I don't quite understand exactly what it means when you initialize variables in certain places, but my code works so this isn't the issue... for now. Anyway, here is a my .h file. Everywhere there is a "----" it just means there is code there.
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
NSInteger charactersLocked[3] = {0,0,1};
int charSel = 0;
#interface Tutorial : UIViewController
{
-------
}
------
#end
So I need to access the array charactersLocked in a different .m file, lets call it File2 and this one File1. When I try to #import "File1.h" in File2.m, the program crashes and gives me this error for both charactersLocked and charSel:
duplicate symbol _charactersLocked in:
/Users/me/Library/Developer/Xcode/DerivedData/SpaceRace-
apawbkpiogvbvddranqfltyybuqr/Build/Intermediates/SpaceRace.build/Debug-
iphoneos/SpaceRace.build/Objects-normal/arm64/Tutorial.o
/Users/me/Library/Developer/Xcode/DerivedData/SpaceRace
apawbkpiogvbvddranqfltyybuqr/Build/Intermediates/SpaceRace.build/Debug-
iphoneos/SpaceRace.build/Objects-normal/arm64/Space.o
I have no idea what this is. I've tried looking for solutions online, but none of them seem to work. I am not importing the .m file by accident. If there is an easier way to just get access to that specific array, please let me know. Sorry if this post was formatted horribly, it is my first time so bear with me. Thank you.
The short answer to your question is located in this answer; you need to declare your variables as extern for the compiler to know that you want to use it in multiple files.
This is very rarely done in Objective-C though, because its heritage as an object-oriented programming language means that global state in programs is most often handled in class methods or singleton classes. Without knowing too much about your program, I am going to guess that you want a singleton class, something like CharacterLocker, which would look like this:
CharacterLocker.h
#interface CharacterLocker : NSObject
{
NSInteger charactersLocked[3];
}
+ (id) sharedObject;
#property NSInteger* charactersLocked;
#end
CharacterLocker.m
#implementation CharacterLocker
#synthesize charactersLocked;
+ (void) sharedObject
{
static CharacterLocker *singleton = nil;
// Required so that multiple calls to sharedObject don't create two
static dispatch_once_t pred;
dispatch_once(&pred, ^{ singleton = [[CharacterLocker alloc] init]; });
return singleton;
}
- (id) init
{
if ( self = [super init] )
{
charactersLocked[0] = 0;
charactersLocked[1] = 0;
charactersLocked[2] = 1;
}
return self;
}
#end
Then, in your code, you call [CharacterLocker sharedObject].charactersLocked to access the array.
How do you define a static extension method in Kotlin? Is this even possible? I currently have an extension method as shown below.
public fun Uber.doMagic(context: Context) {
// ...
}
The above extension can be invoked on an instance.
uberInstance.doMagic(context) // Instance method
but how do I make it static method like shown below.
Uber.doMagic(context) // Static or class method
To achieve Uber.doMagic(context), you can write an extension to the companion object of Uber (the companion object declaration is required):
class Uber {
companion object {}
}
fun Uber.Companion.doMagic(context: Context) { }
This is what the official documentation says:
Kotlin generates static methods for package-level functions. Kotlin
can also generate static methods for functions defined in named
objects or companion objects if you annotate those functions as
#JvmStatic. For example:
Kotlin static methods
class C {
companion object {
#JvmStatic fun foo() {}
fun bar() {}
}
}
Now, foo() is static in Java, while bar() is not:
C.foo(); // works fine
C.bar(); // error: not a static method
I actually had this exact question 30 minutes ago, so I started digging around and couldn't find any solution or workaround for this, BUT while searching I found this section on the Kotlinglang website that states that:
Note that extensions can be defined with a nullable receiver type. Such extensions can be called on an object variable even if its value is null.
So then I had the craziest idea ever, why not define an extension function with a nullable receiver (without actually using that receiver) and then call it on a null object!
So I tried that, and it worked pretty well, but it looked so ugly. It was like this:
(null as Type?).staticFunction(param1, param2)
So I went around that by creating a val in my extensions file of the receiver type that had a value of null and then use it in my other class.
So, as an example, here is how I implemented a "static" extension function for the Navigation class in Android:
In my NavigationExtensions.kt file:
val SNavigation: Navigation? = null
fun Navigation?.createNavigateOnClickListener(#IdRes resId: Int, args: Bundle? = null, navOptions: NavOptions? = null,
navigationExtras: Navigator.Extras? = null) : (View) -> Unit {
//This is just implementation details, don't worry too much about them, just focus on the Navigation? part in the method declaration
return { view: View -> view.navigate(resId, args, navOptions, navigationExtras) }
}
In the code that uses it:
SNavigation.createNavigateOnClickListener(R.id.action_gameWonFragment_to_gameFragment)
Obviously, this isn't a class name, it is just a variable of the class type that has a null value. This is obviously ugly on the extension maker side (because they have to create the variable) and on the developer side (because they have to use the SType format instead of the actual class name), but it is the closest that can be achieved right now compared to actual static functions. Hopefully, the Kotlin language makers will respond to the issue that was created and add that feature in the language.
Since I keep coming across this when searching, here's a different approach I haven't seen anyone mention that works in a static way and it works with generics!
Extension definitions:
// Extension function
fun <T> KClass<T>.doSomething() = /* do something */
// Extension Property
val <T> KClass<T>.someVal get() = /* something */
Usage:
MyType::class.doSomething()
MyType::class.someVal
As you can see, the trick is attaching the extension function to the KClass of the type instead since that can be referenced statically.
You can create a static method with using Companion object like:
class Foo {
// ...
companion object {
public fun bar() {
// do anything
}
}
}
and then you can call it like:
class Baz {
// ...
private fun callBar() {
Foo.bar()
}
}
Recomend you to look at this link. As you can see there, you just should declare method at the top-level of the package (file):
package strings
public fun joinToString(...): String { ... }
This is equal to
package strings;
public class JoinKt {
public static String joinToString(...) { ... }
}
With constans everything are the same. This declaration
val UNIX_LINE_SEPARATOR = "\n"
is equal to
public static final String UNIX_LINE_SEPARATOR = "\n";
I also required the ability to extend a Java object with a static method and found the best solution for me was to create a Kotlin object that extended the Java class and add my method there.
object Colour: Color(){
fun parseColor(r: Int?, g: Int?, b: Int?) = parseColor(String.format("#%02x%02x%02x", r, g, b))
}
invocation:
val colour = Colour.parseColor(62, 0, 100)
I'm also quite fond of having the possibility to add static extension methods in Kotlin. As a workaround for now I'm adding the exntension method to multiple classes instead of using one static extension method in all of them.
class Util
fun Util.isDeviceOnline(context: Context): Boolean {
val connMgr = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val networkInfo = connMgr.activeNetworkInfo
return networkInfo != null && networkInfo.isConnected
}
fun Activity.isDeviceOnline(context: Context) = { Util().isDeviceOnline(context) }
fun OkHttpClient.isDeviceOnline(context: Context) = { Util().isDeviceOnline(context) }
To create an extension method in kotlin you have to create a kotlin file(not a class) then declare your method in the file
Eg:
public fun String.toLowercase(){
// **this** is the string object
}
Import the function in the class or file you are working on and use it.
I've been using C-style functions, but I just learned they can't see instance variables. So I was advised to convert them to Objective-C methods.
NSString* myfunc ( int x )
becomes:
- (NSString *)myfunc:(int)x
and
myString = myfunc(x);
becomes
myString = [myString myfunc:x];
??
This compiles with ominous warnings, but does not work. What have I misunderstood?
It looks like your call is incorrect. Perhaps try:
NSString *myString = [self myfunc:x];
As far as I understand, you send the -myfunc: message to a NSString object. So the -myfunc: method should be declared in NSString class (or a category of NSString).
If this is what you want to do, you don't need to return the object itself as the result of the method: you can modify its instance variables in the method implementation. The method call (or message sending) looks like:
[myString myfunc:x];
If you want to send the message to an object of another class and return a string, your method declaration is correct but must appear in your class implementation and the receiver of the message (this is the item on the left in the square brackets) must be of that class:
#implementation MyClass
-(NSString *)myfunc:(int)x
{
NSString * returnString;
...// do something with x, returnString and instance variables
return returnString;
}
#end;
...
MyClass * myobj = [[MyClass alloc] init];
NSString * myString = [myobj myfunc:42];
As a second answer, I am trying to understand your problem through all your recent questions.
At the beginning, there was a C function returning a pointer to a NSString object:
NSString * myfunc( int x )
{
... // Do something with x
NSString * myString = #"MYDATA";
... // Do something with myString
return myString;
}
Then, you wanted to add in that function some code about an UIImage object:
image1.image = [UIImage imageNamed:#"image1.png"];
You were advised to convert the function to a method. If you want to access .image instance variable, this method has to belong to the class of image1 object (let's say this is AlanImage class). Something like this:
#interface AlanImage : NSObject {
UIImage image;
}
- (NSString *) myfuncWithParam: (int) x;
#end;
#implementation AlanImage
- (NSString *) myfuncWithParam: (int) x
{
NSString * myString = #"MYDATA";
image = [UIImage imageNamed:#"image1.png"];
return myString;
}
#end
Third, you didn't know what was the receiver of the method. My investigations tend to lead to your image object as a good candidate:
aNiceString = [image myfunc:aNiceInteger];
Finally (this question), not getting a satisfying answer, you reworded your third question, with success this time as it happens.
I am curious to get a more complete view of your project in order to give you some hints. Anyway, it seems that you are learning Objective-C and object oriented concepts: congratulations and stay motivated!
You haven't worked out what Object Oriented Programming is. With [theObject method] you can only call methods belonging to the specific instance.
I am not sure that following trick correctly work for a "general" objective-c, but in apple implementation you can do such:
#interface SomeClass: NSObject {
int m_someVariable;
...
};
- (NSString *) someMethod;
...
#end
#implementation SomeClass
...
//pure c function with extra one parameter
//for accessing to instance variables
static NSString privatePlainCeeMethod(SomeClass *my, int fortyTwo) {
NSString *str;
//access to a instance variable as for a usual
//cee structure field: my->fieldName
...
return [NSString stringWithFormat:#"someVariable:%d, fortyTwo:%d",
my->m_someVariable, fortyTwo];
};
- (NSString *) someMethod {
...
return privatePlainCeeMethod(self,42);
};
...
#end
I use such trick to divide a big objc method on observable private simple functions. These functions (a) do not pollute class interface and (b) are invoked faster than objc method.