I have a custom Objective-C class that contains two CGFloats:
#property (nonatomic, assign) IBInspectable CGFloat minimumConstant NS_REFINED_FOR_SWIFT;
#property (nonatomic, assign) IBInspectable CGFloat maximumConstant NS_REFINED_FOR_SWIFT;
Both are marked as IBInspectable. In the initializer of the class I set both bot NaN as I need to represent a difference between 0 and nothing. To make the class nice to use from Swift I marked both properties as NS_REFINED_FOR_SWIFT and created a Swift extension with the refined implementation:
#IBInspectable public var minimumConstant: CGFloat? {
get {
let constant = __minimumConstant
return constant.isNaN ? nil : constant
}
set {
if let constant = newValue {
__minimumConstant = constant
return
}
__minimumConstant = CGFloat.nan
}
}
#IBInspectable public var maximumConstant: CGFloat? {
get {
let constant = __maximumConstant
return constant.isNaN ? nil : constant
}
set {
if let constant = newValue {
__maximumConstant = constant
return
}
__maximumConstant = CGFloat.nan
}
}
This works great when using my class from code. When using Swift NaN will be mapped to nil and I can use optional unwrapping as usual.
The issue is that as soon as I add NS_REFINED_FOR_SWIFT the Interface Builder will no longer recognize my properties as IBInspectable and does not show them.
Is this a known issue? Is there any workaround for this?
I am creating a Universal Class, for SQLite and I am trying to send a block of sqlite3_step, to be processed.
In sqlite3_step, I am passing the struct object statement. But, it seems I need to use pointers.
How can I possibly do ir?
Yeah, something like this should work:
typedef struct
{
int data;
}MyStruct;
#interface Foo()
#property (nonatomic, copy) void (^myBlock)(MyStruct);
#end
#implementation Foo
- (void) someMethod {
self.myBlock = ^(MyStruct theStruct) {
NSLog(#"Value of data in the struct %i", theStruct.data);
};
MyStruct theStruct;
theStruct.data = 5;
self.myBlock(theStruct);
}
#end
I have a property like this on a class:
#property (nonatomic, strong) void (^ifSuccess)(MyClass *myObject);
Now I need to do this inside a C function:
if (self.ifSuccess) {
self.ifSuccess(value);
}
but this will not work, because inside a C function I will not have references to self. So I need to pass the block as a parameter to the C function. Something like this:
void myFunction(myClass *object, XXX) {
}
where XXX is probably
void(^ifSuccess)()
making the function like
void myFunction(myClass *object, void(^ifSuccess)()) {
}
Please confirm if this is correct.
The problem is that I cannot pass self.ifSuccess in a call to myFunction.
This will not work
myFunction(object, self.ifSuccess);
so I need a way to read self.ifSuccess block and pass it to the function.
How?
note: yes, this needs to be in C
*ONE:-*Yes you can pass reference to self inside c method.
*TWO:-*Declaring objective c block can be syntactically daunting so I like to be little systematic.
i will do
typedef void (^ifSuccess)(MyClass *myObject);
now i will declare the property as
#property (nonatomic, strong) ifSuccess mySuccessBlock;
your function becomes
void myFunction(myClass *object,ifSuccess blockParameter) {
}
First day learning Objective-C but have a java background. I'd like to use the same variable name for my parameter that I do for my instance variable. In java we do it like this
public class Person
{
private String name;
private String age;
public void setName(String name)
{
this.name = name;
}
public void setAge(String age)
{
this.age = age;
}
}
In objective c so far I have this
#interface Person : NSObject
{
int age;
int name;
}
-(void) setAge:(int) age;
-(void) setName:(int) name;
-(int) getAge;
-(int) getName;
#end
#implementation Person
-(void) setName:(int) w
{
weight = w;
}
-(void) setAge:(int) a
{
age = a;
}
-(int) getName
{
return name;
}
-(int) getAge
{
return age;
}
#end
In Objective-C, you can define your own accessors or use #syntehsize to create them automatically for you.
In the case where you want to define accessors manually, setters are declared like this:
- (void)setName:(NSString *)name {
self.name = name;
}
- (void)setAge:(NSInteger)age {
self.age = age;
}
For getters, you simply declare them as follows:
- (NSString *)name {
return self.name;
}
- (NSInteger)age {
return self.age;
}
Objective-C programmers don't like typing, so we do it like this:
#interface Person : NSObject
#property(nonatomic, copy) NSString *name;
#property(nonatomic, assign) int age;
#end
#implementation Person
#end
You may want to start by reading Apple's Objective-C Programming Language introduction.
in ObjectiveC the way to refer to 'this' is 'self'
You have this in ObjectiveC because you are using C style variables. If you declare that variables as ObjectiveC properties and use the correct synthesize instruction:
#property (int) age;
#synthesize age;
Then you can refer to them through self.age
self.age = age;
in the implementation file. This will internally call the -(void)setAge:(int)age method and the -(int) age methods which will be defined automatically.
Finally since an ObjectiveC object is nothing more than a pointer to a C struct you can access variables by skipping ObjectiveC by using the syntax to refer to fields of a pointer to a struct: self->age = age
I understand that Properties in Objective-C allows us to compactly define:
setter
getter
data
I would like to use Properties, but it would be nice if I could decouple the data from the getter/setter.
In other words, I like the getter/setter interface of Properties, but I would like to define my own internal representation of data.
For instance, if I were to define MyOwnTime class, I want getters/setters for Properties like hour, date, and minute (as a consumer, I want to be able to set them and get them). However, to save memory in the representation, rather than store date, month, year, hour, minute, second, etc..., I prefer to store secondsSinceEpoch as an unsigned long.
In my situation should I/can I use Properties? How would I do this? Or should I manually roll my own setters and getters?
You can certainly do this. Indeed, it's pretty common. Since the mapping to data is not direct, you cannot synthesise the methods, you have to write the getters and setters manually. But the property will work like any other.
As a simple dummy example:
#interface BytePair
{
UInt16 data;
}
#property UInt8 loByte;
#property UInt8 hiByte;
#end
#implementation BytePair
- (UInt8) loByte
{
return (UInt8) data & 0xff;
}
- (void) setLoByte:(UInt8)lo
{
data = (data & 0xff00) | lo;
}
- (UInt8) hiByte
{
return (UInt8) (data & 0xff00) >> 8;
}
- (void) setHiByte:(UInt8)lo
{
data = (data & 0xff) | (lo << 8);
}
#end
Or whatever. You get the idea.
Of course you can :
#interface MyObject : NSObject
{
int toto;
}
#property(nonatomic, setter=mySetterMethod:, getter=myGetterMethod) int toto;
-(void) mySetterMethod:(int) t;
-(void) myGetterMethod;
Or you can also override the setter and getter default methods, in my case (in the .m file) :
-(int) toto
{
return toto;
}
-(void) setToto:(int) t
{
toto = t;
}
Declare a
#property (nonatomic, assign) sometype somename
in the interface as normal. Then instead of writing
#sythesize somename = _somename
in the implementation, you write
-(sometype)somename {
return whatever;
}
-(void)setSomename(sometype)newValue {
whatever;
}
You don't need to use the #property notation at all. Just do this:
#interface MyObject
- (id)foo;
- (void)setFoo:(id)newFoo;
#end
Then, elsewhere you can do myObject.foo = #"bar";.
Calling myObject.foo is exactly the same as [myObject foo] or [myObject setFoo:foo]. It has nothing to do with properties, it just happens to be most commonly used for them.
And the #property syntax is just a formal way of declaring properties allowing you to do more advanced stuff (like nonatomic). If you're defining your own methods, instead of letting the compiler define them for you, then there isn't much point to using #property.
If you have ARC disabled, then you might want to look into how to properly memory manage a property, as there are some non-obvious edge cases where you can get into trouble defining your own data storage code.
You can, it's common, and pretty easy to do.
As with a standard property, you don't even need to declare an instance variable for that and can still #synthesize your property (contrary to what other answers are saying), you simply have to override the setter of the property:
#interface MyObject : NSObject
#property(nonatomic, copy) NSString* myprop; // like any other property
#property(nonatomic, readonly) BOOL hasProp;
#end
#implementation MyObject
#synthesize myprop = _myprop; // optional with latest LLVM compiler, will generate the _myprop instance variable at compile time
// Override default setter for myprop
-(void)setMyprop:(NSString*)newvalue
{
if (_myprop != newvalue)
{
[_myprop release]; // release only necessary if not using ARC
_myprop = [newvalue retain]; // retain only necessary if not using ARC
// And/Or whatever you want your custom setter to do
}
}
// You can override default "-(NSString*)myprop" getter too if you want
// You you can keep the default getter implementation and only override the setter.
// Or vice-versa. It's really up to you
// Another example: we created a #property(readonly) hasProp and implement its getter by ourselves, without any dedicated instance variable
-(BOOL)hasProp
{
return (self.myprop != nil);
}
#end