Objective C Extension equivalent to Swift Extensions? - objective-c

What would be the equivalent of extensions in Objective-C as in Swift? Is it the same as creating a class function within a class?
extension CGRect{
static func rectWithTwoPoints(p1:CGPoint,p2:CGPoint) -> CGRect
{
return CGRectMake(min(p1.x, p2.x),min(p1.y, p2.y),fabs(p1.x - p2.x),fabs(p1.y - p2.y));
}
}

In objective C its category and in swift its extension
1.Click File -> New -> File
2.Select Objective-C file under Sources in iOS or Mac OS respectively and Click Next
3.Now select File Type as Category
Select UIView as baseclass of category and set name as "UIView+CGRect"
And you can add your methods like
UIView+CGRect.h of category :
+ (CGRect) rectWithTwoPoints:(CGPoint) p1 andWith:(CGPoint) p2;
UIView+CGRect.m of category :
+ (CGRect) rectWithTwoPoints:(CGPoint) p1 andWith:(CGPoint) p2 {
return CGRectMake(MIN(p1.x, p2.x), MIN(p1.y, p2.y), fabs(p1.x - p2.x), fabs(p1.y - p2.y));
}
And just import your category in view controller where you want to use it and access like
In ViewController.h
#import "UIView+CGRect.h"
And code will be
CGrect rect = [UIView rectWithTwoPoints:POINT_ONE andWith:rectWithTwoPoints:POINT_TWO];
You will get desired result.

There is no single equivalent, they're different languages with different capabilities.
For your example the 'equivalent' would be a utility function declared somewhere, likely just in a file, because CGRect isn't a class. It would be a C function, not an Obj-C method.
You could even declare a macro for it.

In Objective-C structures are not similar to classes, but plain C. Therefore they do not have functions associated with them. The usual pattern is that there are (C) functions dealing with the structure. You will find a bunch of them in the headers, for example:
CGRect CGRectMake ( CGFloat x, CGFloat y, CGFloat width, CGFloat height );
If you want to have an extra function, just write it:
CGRect rectWithTwoPoints(CGPoint p1, CGPoint p2)
{
return CGRectMake(min(p1.x, p2.x),min(p1.y, p2.y),fabs(p1.x - p2.x),fabs(p1.y - p2.y));
}
And put a prototype into a header, if you want to use it outside the defining compilation unit:
CGRect rectWithTwoPoints(CGPoint p1, CGPoint p2); // <- There is a semicolon for prototyping

Related

Keeping Swift Double precision in Objective C

A double created in Swift
let d: Double = 1.0
when passed to Objective C, will not preserve the .0. It ends up as 1.
Is there a way preserve .0 for whole doubles in Objective C?
Edit:
Here's what I'm doing:
Parent.m
#implementation Parent
-(void)log:(NSDictionary*)data {
}
#end
Parent.h
#interface Parent : NSObject
-(void)log:(NSDictionary*)data;
#end
Child.swift
class Child: Parent {
func log() {
let measure = Double(1)
let isLoggedIn = false
let data: [String: Any] = ["is_logged_in": isLoggedIn, "measure": measure]
log(data) // calling parent method, measure ends up as 1
}
}
From the wording of your question you might need to research the difference between a double value (the same in both languages) and a textual representation of a double value (which your question suggests might not default to the same in both languages).
Once you are clear on that look up the NSString method stringWithFormat and see if you can produce the format you require using that. (NSLog() supports the same formatting.)
If the above fails to meet your requirements look up NSNumberFormatter.
HTH

How to document a struct within a struct in XCode (Swift or Obj-C)

We all know that when documenting a struct, you can use #struct for your struct and use #field to explains the content within the struct.
But how to document a struct with some fields that is within another struct?
In Swift, the example code will be:
struct Constants{
static let kButtonHeight : CGFloat = 0
struct Color {
static let kCloud: UIColor = UIColor(red: 236/255, green: 240/255, blue: 241/255, alpha: 1.0)
}
}
Thank you so much!
If you're doing this in Swift, you can prefix anything (type, property, or instance, etc.) with either single-line comments marked by /// or multi-line comments beginning with /**. So your documentation could simply be:
/// A global container for all constants
struct Constants{
/// The default button height
static let kButtonHeight : CGFloat = 0
/// Constant UIColor instances for my app
struct Color {
/// The cloud color - a very pale blue-white
static let kCloud: UIColor = UIColor(red: 236/255, green: 240/255, blue: 241/255, alpha: 1.0)
}
}
The documentation attaches immediately -- option click on a name and you get the relevant documentation:
I would define the Color struct outside (and before/above) the definition of Constants, and then the definition of constants would have a member of type Color, but without the 'nested' definitions. If you consider CGRect, this is a 'struct of structs' (a CGPoint and a CGSize) but those member structs are perfectly usable on their own as well..

Adding Objective-C method to class at runtime

I'm trying to support newly added methods of NSColor in 10.9 on older systems. Pre-10.9 I had these in a category which allowed my to unify code between Mac and iOS. Now that 10.9 has these methods, I get odd drawing wherever I use them. I want to add these methods dynamically to older runtimes and I've found several references for how to do it using class_addMethod. The problem is, that even though addMethod returns success, the methods aren't called.
NSColor *
fColorWithWhite(id self, SEL _cmd, float white, float alpha) {
return [NSColor colorWithDeviceWhite: white
alpha: alpha];
}
NSColor *
fColorWithRedGreenBlue(id self, SEL _cmd, float red, float green, float blue, float alpha) {
return [NSColor colorWithDeviceRed: red
green: green
blue: blue
alpha: alpha];
}
+ (void)addLegacySupport {
Class class = NSClassFromString(#"NSColor");
BOOL success = class_addMethod(class, #selector(colorWithWhite:alpha:), (IMP)fColorWithWhite, "##:ff");
NSLog(#"colorWithWhite:alpha: - %i", success);
success = class_addMethod(class, #selector(colorWithRed:green:blue:alpha:), (IMP)fColorWithRedGreenBlue, "##:ffff");
NSLog(#"colorWithRed:green:blue:alpha: - %i", success);
}
Any pointers would be much appreciated.
You are trying to add class methods. You need to add them to the metaclass.
Class meta_cls = objc_getMetaClass("NSColor");
class_addMethod() adds an instance method to the class. You are trying to add a class method. Thus, you need to add the method to the metaclass (classes are instances of their metaclasses), which you can get by calling object_getClass() with the class as the argument:
Class metaclass = object_getClass(NSClassFromString(#"NSColor"));
BOOL success = class_addMethod(metaclass, #selector(colorWithWhite:alpha:), (IMP)fColorWithWhite, "##:ff");

Store an array of NSObject Pointers in C array

I'd like to create an NSObject subclass that contains a few member vars:
#interface PointMass : NSObject
{
CGPoint mCurPosition;
CGPoint mLastPosition;
CGPoint mAcceleration;
}
-(id) initWithPosition:(CGPoint*) pos;
#import "PointMass.h"
#implementation PointMass
-(id) initWithPosition:(CGPoint*)pos
{
mCurPosition = *pos;
mLastPosition = *pos;
mAcceleration = ccp(0,0);
return self;
}
#end
And I would like to create a C-style array to hold a bunch of them within a cocos2d class:
// mNumPoint declared in interface, I've set it to 100
PointMass *pointMassList;
pointMassList = malloc(sizeof(PointMass*) * mNumPointMass);
for (int = 0; i < mNumPointMass; i++)
{
CGPoint point = ccp(100,100);
PointMass *p = [[PointMass alloc] initWithPosition: &point];
pointMassList[i] = p;
}
But I get an error
Expected method to write array element not found on object of type 'PointMass *'
Do I need to tell the compiler more about my PointMass Object if I want to store pointers to it in a C array?
I'm basically trying to have a play around with some particle math on iPhone without needing to unpack points from an NSArray constantly if it isn't clear what I'm trying to achieve here.
If I've gone about this in a backwards way I'd love to be corrected - it has been a while since I wrote vanilla C and I'm a little rusty!
it has been a while since I wrote vanilla C
You should still be able to make the distinction between a pointer-to-T and a pointer-to-pointer-to-T (T being PointMass in this case). You want to store an array of PointMass *, and not an array of PointMass (which you couldn't do anyway). So change the declaration of pointMassList to
PointMass **pointMassList;
and it will work. However, if you're using Objective-C anyway, why don't you simply store the instances into an NSArray?

What is "CG_INLINE CGRect" definition in Objective C called?

What is the following structure called in Objective C,
CG_INLINE CGRect
CGRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height)
{
CGRect rect;
rect.origin.x = x; rect.origin.y = y;
rect.size.width = width; rect.size.height = height;
return rect;
}
I want to create my own definition for making an object that would hold multiple parameters that I pass. Currently I am using a static method within a class that would take multiple parameters and return an object. But this syntax of CGRectMake is a perfect solution i could use. What is the structure actually called in Objective C syntax?
CGRectMake() is a function. Functions are a C language feature, not unique to Objective-C. Therefore, they don't have a special name in Objective-C. They're called C functions.
If you're asking about this seemingly cryptic syntax:
CG_INLINE CGRect
CGRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height)
CG_INLINE is a special token that does nothing more than declare a function as inline. You can find a description of CG_INLINE in this question:
What does CG_INLINE do?
CGRect is the return type. The line break that follows is mere whitespace; it's a somewhat common code-formatting convention in C to break a line after the return type in a function definition.
CGRectMake is the function name.
The rest that follows is its argument list and function body.
If you want to create a function, you can place its definition in your .m file, with a corresponding forward declaration in the .h file.