Getter for a block on a class? - iphone

I am creating a property on a class that is gonna be a block.
It is being defined like
#property (nonatomic, strong) void (^ myBlock)();
I would like to do lazy creation of that property, so I want to create a getter for that block to run when the the property is used by some code.
If the property was not a block and was a NSArray for example, I would do the setter like this:
#synthesize myProperty = _myProperty;
- (NSArray *)myProperty {
if (_myProperty) {
_myProperty = [[NSArray alloc] init];
}
return _myProperty;
}
How do I do a getter (lazy instantiation) for a property that is a block?
NOTE: this block is inside a singleton.
thanks

#property (nonatomic, copy) void (^ myBlock)();
- (void (^)())myBlock {
if (!_myBlock) {
self.myBlock = ^ () {
NSLog(#"Do something");
};
}
return _myBlock;
}

in h
typedef BOOL (^MyProcessorBlock)(id param1);
#property (nonatomic, copy) MyProcessorBlock myBlockProperty
in m (if you use old objc pre 2.0, pre summer 2012)
#synthesize myBlockProperty = _myBlockProperty;
in any case in m file
- (MyBlock)myBlockProperty {
if(!_myBlockProperty) {
_myBlockProperty = ^(self) { ..... };
}
return _myBlockProperty;
}

Related

Using objective C++, can you create a property that is a C++ class and the getter returns a reference

I want to do this but have not seen it anywhere.
#property (nonatomic) MyCPPClass &myInstance;
I need it to write a getter that returns a reference and not a copy.
- (MyCPPClass &)myInstance {
return _myInstance;
}
Or can it only be done with an iVar and writing my own getter and setter.
You may use a private instance variable for that:
#interface MyObjCPPClass
#property (nonatomic) MyCPPClass &myInstance;
#end
#implementation MyObjCPPClass {
MyCPPClass _myInstance;
}
- (MyCPPClass &)myInstance {
return _myInstance;
}
- (void)setMyInstance:(MyCPPClass &)instance {
_myInstance = instance;
}
#end

Making an Integer Array in Objective-C

I want to have an internal int array for my class, but I can't seem to get XCode to let me. The array size needs to be set on initialization so I can't put the size directly into the interface.
At the moment I've been trying:
#interface TestClass : NSObject {
int test[];
}
But it tells me that I'm not allowed. How to I refer to it in my interface, and then how do I allocate it when I create the implementation?
Sorry for a somewhat standard sounding question, but I can't seem to find the answer I need from searching.
edit: I want to use an array because it's apparently much faster than using an NSArray
You can use a number of methods to overcome this problem, but the easiest is to simply make the instance variable a pointer, like this:
#interface TestClass : NSObject {
int *test;
}
#property int *test;
#end
Synthesizing the property will give it getter and setter methods which you can use to set its contents:
#implementation TestClass
#synthesize test;
//contents of class
#end
You can then use it like this:
TestClass *pointerTest = [[TestClass alloc] init];
int *array = (int *)malloc(sizeof(int) * count);
//set values
[pointerTest setTest:array];
[pointerTest doSomething];
However, using objects like NSNumber in an NSArray is a better way to go, perhaps you could do something like this:
#interface TestClass : NSObject {
NSArray *objectArray;
}
#property (nonatomic, strong) NSArray *objectArray;
#end
#implementation TestClass
#synthesize objectArray;
//contents of class
#end
You can then set its contents with a pointer to an NSArray object:
NSArray *items = [NSArray arrayWithObjects:[NSNumber numberWithInt:1], [NSNumber numberWithInt:2], nil];
TestClass *arrayClass = [[TestClass alloc] init];
[arrayClass setItems:items];
[arrayClass doSomething];
When retaining objects upon setting them (like the previous example), always make sure you deallocate the object in the classes dealloc method.
A C array is just a sufficiently sized raw memory buffer. Foundation has a nice wrapper around raw memory that frees you from all the manual memory management: NSMutableData
The following approach gives you automatic memory management plus proper encapsulation.
#interface TestClass : NSObject
#property (nonatomic, readonly) int *testArray;
#property (nonatomic, readonly) NSUInteger testArraySize;
#end
#implementation TestClass
{
NSMutableData *_testData;
}
- (id)initWithSize:(NSUInteger)size
{
self = [self init];
if (self != nil) {
_testData = [NSMutableData dataWithLength:size];
}
}
- (int *)testArray
{
return [_testData mutableBytes];
}
- (NSUInteger)testArraySize
{
return [_testData length];
}
#end
As you see, the ivar does not have to be declared in the #interface.
Try something like this:
#interface TestClass : NSObject
{
int *_test;
}
#property (assign) int *test;
#end
#implementation TestClass
- (instancetype)init
{
if (self = [super init])
{
_test = malloc(sizeof(int) * 20);
}
return self;
}
- (int *)test
{
return _test;
}
- (void)setTest:(int*)test
{
memcpy(&_test, &test, sizeof(_test));
}
- (void)dealloc
{
free(_test);
}
#end

Variables in a class

#interface characterclass : CCSprite
{
bool alive;
int speed;
int jumpamount = 10; <--- error
}
#property bool alive;
#property int speed;
#property int jumpamount;
#end
how do i do this like in my code, I want to have a variable in my class that equals 10.
You need to assign these values in the initializer of your class's instances. Create an instance method called - (id)init:
- (id)init{
self=[super init];
if (self) {
jumpamount=10;
}
return self;
}
Note that you no longer need to declare your ivars like that. #property will create an ivar for you.

How can I create a wrapper to use blocks for a class that uses callbacks?

I'm diving into iOS programming and I'm learning how to use blocks. I have a sucky, over-engineered library that I'm using in my project and it uses a single callback method to handle all data requests...
#protocol SuckyClassDelegate <NSObject>
-(void)returnedSuckyData:(NSMutableDictionary*)data;
#end
#interface SuckyClass: NSObject
#property (nonatomic, weak) id<SuckyClassDelegate> delegate;
-(void)getSuckyData;
#end
#interface MyViewController: UIViewController <SuckyClassDelegate>
-(void)requestDataFromSuckyClass;
#end
I'd like to create a wrapper class for the SuckyClass that allows me to use blocks when I need to access data from the SuckyClass, but I don't know how to do this. I'd like to have something like this...
#interface SuckyClassWrapper
- (void)requestDataWithSuccessBlock:(void(^)((NSMutableDictionary*)data))successBlock;
#end
#implementation MyViewController
-(void)requestDataFromSuckyClass {
SuckyClassWrapper *wrapper = [[SuckyClassWrapper alloc] init];
[wrapper requestDataWithSuccessBlock:^(NSMutableDictionary *data) {
NSLog(#"%#", data);
}
}
#end
...but I can't figure out how to convert the callback process into blocks. Can anyhow give me some direction here?
Thanks in advance for your wisdom!
By the way, I just whipped up the code without testing it, so I apologize if there are any typos.
The trick is to copy the completion block to a class iVar that you can then call later.
#property (nonatomic, copy) void (^errorHandler)(NSError *);
#property (nonatomic, copy) void (^successHandler)(NSString *);
Here is a method that saves two blocks for use later and then calls another class method:
- (void)methodWithErrorHandler:(void(^)(NSError *error))errorBlock successHandler: (void(^)(NSString *data))successBlock
{
// Copy the blocks to use later
self.successHandler = successBlock;
self.errorHandler = errorBlock;
// Run code
[self doOtherThings];
}
Later - when what we want to do has completed, we have another method that we call to run the blocks. In this silly example code we check to see if a class property self.error is nil. If it is not nil, we send that error to our saved error block. If it is nil, we pass self.data to the success block.
- (void)finishThingsUp
{
// Check to see if we should call the error block or the success block
if (self.error) {
self.errorHandler(self.error);
} else {
self.successHandler(self.data);
}
// Clean up the blocks
self.errorHandler = nil;
self.successHandler = nil;
}
We could use like this:
typedef void (^SuccessDataBlock)(NSMutableDictionary *);
#interface SuckyClassWrapper : NSObject <SuckyClassDelegate>
#property (nonatomic, retain) NSData *inputData;
#property (nonatomic, copy) SuccessDataBlock completionHandler;
+ (id)requestData:(NSData *)data successBlock:(SuccessDataBlock)handler;
#end
#implementation SuckyClassWrapper
#synthesize inputData;
#synthesize completionHandler;
- (id)initWithData:(NSData *)data completionHandler:(SuccessDataBlock)handler
{
self = [super init];
if (self != nil)
{
inputData = [data retain];
self.completionHandler = handler;
}
return self;
}
+ (id)requestData:(NSData *)data successBlock:(SuccessDataBlock)handler
{
return [[[self alloc] initWithData:data completionHandler:handler] autorelease];
}
//implement SuckyClass delegate
- (void)returnedSuckyData:(NSMutableDictionary *)data
{
self.completionHandler(data);
}
#end
Usage:
SuckyClassWrapper *wrapper = [SuckyClassWrapper requestData:data successBlock:^(NSMutableDictionary *successData) {
//your code here
}];

Override #synthesize method?

I have one class called dog and another class called cat.
Dog has an variable, "name" declared with #property in the .h file.
In the cat class, I have set the name by using the command, myDog.name = "buster", after creating the variable "myDog" of type dog.
I would like to do additional operations when the name is set by overriding the set method normally created by the #synthesize command.
How can I do that? Thanks for the help!
All you have to do is leave the #synthesize then create whichever methods you want to be custom. Example:
In .h
#property(nonatomic, retain)NSString *Bob;
In .m
#synthesize bob;
-(void)setBob:(NSString *)bobValue{
[bobValue retain];
[bob release];
bob = bobValue;
//your custom stuffs here
}
This has been pretty much answered on SO already - see Objective-C synthesize property name overriding for details. In particular, #Dev Kanchen's answer which includes example code.
You cannot override (and call it within) a synthesized method from within the very same class.
You can however override it from a subclass (or rather: synthesize it in an abstract superclass).
If you simply want to perform additional (vs. different) operations upon property change I would use KVO by simply adding each dog as observer to its own "name" property in -(id)init;.
Edit:
There is a way to add additional logic to synthesized methods from within the same class:
Define a private intermediate property in a class extension.
I've attached source code for a class which uses synthesized properties and takes care(sic!) of keeping the dog's owner in sync with its own identity.
Dog.h:
#import <Foundation/Foundation.h>
#interface Dog : NSObject {
#private
NSString *name;
NSString *owner;
}
#property (nonatomic, readwrite, retain) NSString *name;
#property (nonatomic, readwrite, retain) NSString *owner;
#end
Dog.m:
#import "Dog.h"
#interface Dog ()
#property (nonatomic, readwrite, retain) NSString *primitiveName;
#end
#implementation Dog
#dynamic name;
#synthesize primitiveName = name;
#synthesize owner;
- (id)init {
if ((self = [super init])) {
name = #"Snowy";
owner = #"Tintin";
}
return self;
}
- (void)dealloc {
[super dealloc];
}
- (NSString *)name {
return self.primitiveName;
}
- (void)setName:(NSString *)aName {
self.primitiveName = aName;
if ([aName isEqualToString:#"Snoopy"]) {
self.owner = #"Charlie Brown";
}
else if ([aName isEqualToString:#"Snowy"]) {
self.owner = #"Tintin";
}
}
- (NSString *)description {
return [NSString stringWithFormat:#"<%# name:'%#' owner:'%#'>", [self class], self.name, self.owner];
}
#end
Test:
Dog *dog = [[Dog alloc] init];
NSLog(#"%#", dog);
dog.name = #"Snoopy";
NSLog(#"%#", dog);
dog.name = #"Snowy";
NSLog(#"%#", dog);
Result:
<Dog name:'Snowy' owner:'Tintin'>
<Dog name:'Snoopy' owner:'Charlie Brown'>
<Dog name:'Snowy' owner:'Tintin'>