Making an Integer Array in Objective-C - iphone

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

Related

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
}];

Instance class or method without an interface?

Got this code:
#import <Foundation/Foundation.h>
#interface CalculatorBrain : NSObject
- (void)pushOperand:(double)operand;
- (double)performOperation:(NSString *)op;
#property (nonatomic, readonly) id program;
+ (NSString *)descriptionOfProgram:(id)program;
+ (double)runProgram:(id)program;
#end
And this one:
#import "CalculatorBrain.h"
#interface CalculatorBrain()
#property (nonatomic, strong) NSMutableArray *programStack;
#end
#implementation CalculatorBrain
#synthesize programStack = _programStack;
- (NSMutableArray *)programStack
{
if (_programStack == nil) _programStack = [[NSMutableArray alloc] init];
return _programStack;
}
- (id)program
{
return [self.programStack copy];
}
+ (NSString *)descriptionOfProgram:(id)program
{
return #"blablabla";
}
- (void)pushOperand:(double)operand
{
[self.programStack addObject:[NSNumber numberWithDouble:operand]];
}
- (double)performOperation:(NSString *)operation
{
[self.programStack addObject:operation];
return [[self class] runProgram:self.program];
}
+ (double)popOperandOffProgramStack:(NSMutableArray *)stack
{
double result = 0;
return result;
}
+ (double)runProgram:(id)program
{
NSMutableArray *stack;
if ([program isKindOfClass:[NSArray class]]) {
stack = [program mutableCopy];
}
return [self popOperandOffProgramStack:stack];
}
#end
The code is fine an it runs, so the question is, Where is declared popOperandOffProgramStack in the interface? why it compiles and it's okay? it should crash but I can not find an explanation to this....
Thank you!
You only need to declare methods in the #interface in the .h file if you're exposing them to the world. Otherwise, no declaration needed.
And nowadays, the order that they appear in the implementation doesn't matter, either. Historically, if the method was implemented later in the #implementation than where it was invoked, you needed to have the method declared above (generally in the #interface). Now the compiler doesn't care whether the implementation is earlier or later in the .m file.
the compiler can sees its definition:
+ (double)popOperandOffProgramStack:(NSMutableArray *)stack
{
double result = 0;
return result;
}
so it is able to confirm it has been declared, the parameter types, and return type.
also - in older compilers, it would need to precede usage, but not anymore if used in the #implementation scope.
even if it were not declared, objc is weak enough that it would not be a compiler error (warning, perhaps). exception: the method must be visible if you're using ARC. the compiler needs to know the reference counting semantics and parameter types when ARC is enabled.

how to pass string value from one class to another

I just want to know that how to pass the string value from one class to another..
Actually i have two classes.In first class i fetch string value from the array and i just want to use this string value into my second class.Now i don't know how to pass value between this two classes.Please give me some idea to do that.Should i use some class method to pass the value.But i don't know how to use this class methods.How i create the class methods to set the values from one class and then get the same value from class methods.
Thanks for help
Class1.h:
#interface Class1 : NSObject
{
NSArray *arr;
}
- (NSString *)myString;
#end
Class1.m:
#implementation Class1
- (NSString *)myString
{
return [arr objectAtIndex:0];
}
#end
Class2.h:
#interface Class2 : NSObject
{
}
- (void)methodThatUsesStringFromClass1:(Class1 *)c1;
#end
Class2.m:
#implementation Class2
- (void)methodThatUsesStringFromClass1:(Class1 *)c1
{
NSLog(#"The string from class 1 is %#", [c1 myString]);
}
#end
The simplest way is to define public #property in class where you want to pass your object, for example, for NSString:
// CustomClassA.h
#interface CustomClassA : NSObject
{
}
#property (nonatomic, retain) NSString *publicString;
#end
// CustomClassA.m
#implementation CustomClassA
#synthesize publicString;
#end
In your sender:
//somewhere defined CustomClassA objectA;
[objectA setPublicString:#"newValue"];
But you should understand what means retain, #synthesize and other. Also it is not your current question.
you can use appDelegate.YourStringVaraible =#"store your string";
and then use this YourStringVaraible in any class by using appDelegate.YourStringVaraible
pass the string parameter by overriding the init method.
Class1.m
#implementation Class1
Class2 *class2 = [[Class2 alloc] initWithString:myString];
...
#end
Class2.h
#interface Class2 : NSObject
{
NSString *string2;
}
#end
Class2.m
-(id) initWithString:(NSString*)str {
self = [super init];
if(self) {
string2 = str;
}
return(self);
}

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'>

How to handle Objective-C protocols that contain properties?

I've seen usage of Objective-C protocols get used in a fashion such as the following:
#protocol MyProtocol <NSObject>
#required
#property (readonly) NSString *title;
#optional
- (void) someMethod;
#end
I've seen this format used instead of writing a concrete superclass that subclasses extend. The question is, if you conform to this protocol, do you need to synthesize the properties yourself? If you're extending a superclass, the answer is obviously no, you do not need to. But how does one deal with properties that a protocol requires to conform to?
To my understanding, you still need to declare the instance variables in the header file of an object that conforms to a protocol that requires these properties. In that case, can we assume that they're just a guiding principle? CLearly the same isn't the case for a required method. The compiler will slap your wrist for excluding a required method that a protocol lists. What's the story behind properties though?
Here's an example that generates a compile error (Note: I've trimmed the code which doesn't reflect upon the problem at hand):
MyProtocol.h
#protocol MyProtocol <NSObject>
#required
#property (nonatomic, retain) id anObject;
#optional
TestProtocolsViewController.h
- (void)iDoCoolStuff;
#end
#import <MyProtocol.h>
#interface TestProtocolsViewController : UIViewController <MyProtocol> {
}
#end
TestProtocolsViewController.m
#import "TestProtocolsViewController.h"
#implementation TestProtocolsViewController
#synthesize anObject; // anObject doesn't exist, even though we conform to MyProtocol.
- (void)dealloc {
[anObject release]; //anObject doesn't exist, even though we conform to MyProtocol.
[super dealloc];
}
#end
The protocol is just telling everyone that knows about your class through the protocol, that the property anObject will be there. Protocols are not real, they have no variables or methods themselves - they only describe a specific set of attributes that is true about your class so that objects holding references to them can use them in specific ways.
That means in your class that conforms to your protocol, you have to do everything to make sure anObject works.
#property and #synthesize are at heart two mechanisms that generate code for you. #property is just saying there will be a getter (and/or setter) method for that property name. These days #property alone is enough to also have methods and a storage variable created for you by the system (you used to have to add #sythesize). But you have to have something to access and store the variable.
Here's an example of mine that works perfectly, the protocol definition first of all:
#class ExampleClass;
#protocol ExampleProtocol
#required
// Properties
#property (nonatomic, retain) ExampleClass *item;
#end
Below is a working example of a class supporting this protocol:
#import <UIKit/UIKit.h>
#import "Protocols.h"
#class ExampleClass;
#interface MyObject : NSObject <ExampleProtocol> {
// Property backing store
ExampleClass *item;
}
#implementation MyObject
// Synthesize properties
#synthesize item;
#end
all you have to do really is to drop a
#synthesize title;
in your implementation and you should be all set. it works the same way as just putting the property in your class interface.
Edit:
You may want to do this more specifically:
#synthesize title = _title;
This will fall in line with how xcode's automatic synthesis creates properties and ivars if you use auto-synthesis, so that way if your class has properties from a protocol and a class, some of your ivars won't have the different format which could impact readability.
Suppose I have MyProtocol that declares a name property, and MyClass that conforms to this protocol
Things worth noted
The identifier property in MyClass declares and generates getter, setter and backing _identifier variable
The name property only declares that MyClass has a getter, setter in the header. It does not generate getter, setter implementation and backing variable.
I can’t redeclare this name property, as it already declared by the protocol. Do this will yell an error
#interface MyClass () // Class extension
#property (nonatomic, strong) NSString *name;
#end
How to use property in protocol
So to use MyClass with that name property, we have to do either
Declare the property again (AppDelegate.h does this way)
#interface MyClass : NSObject <MyProtocol>
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSString *identifier;
#end
Synthesize ourself
#implementation MyClass
#synthesize name;
#end
Example: 2 classes (Person and Serial) want use service of Viewer... and must conform to ViewerProtocol. viewerTypeOfDescription is a mandatory property subscriber classes must conform.
typedef enum ViewerTypeOfDescription {
ViewerDataType_NSString,
ViewerDataType_NSNumber,
} ViewerTypeOfDescription;
#protocol ViewerProtocol
#property ViewerTypeOfDescription viewerTypeOfDescription;
- (id)initConforming;
- (NSString*)nameOfClass;
- (id)dataRepresentation;
#end
#interface Viewer : NSObject
+ (void) printLargeDescription:(id <ViewerProtocol>)object;
#end
#implementation Viewer
+ (void) printLargeDescription:(id <ViewerProtocol>)object {
NSString *data;
NSString *type;
switch ([object viewerTypeOfDescription]) {
case ViewerDataType_NSString: {
data=[object dataRepresentation];
type=#"String";
break;
}
case ViewerDataType_NSNumber: {
data=[(NSNumber*)[object dataRepresentation] stringValue];
type=#"Number";
break;
}
default: {
data=#"";
type=#"Undefined";
break;
}
}
printf("%s [%s(%s)]\n",[data cStringUsingEncoding:NSUTF8StringEncoding],
[[object nameOfClass] cStringUsingEncoding:NSUTF8StringEncoding],
[type cStringUsingEncoding:NSUTF8StringEncoding]);
}
#end
/* A Class Person */
#interface Person : NSObject <ViewerProtocol>
#property NSString *firstname;
#property NSString *lastname;
#end
#implementation Person
// >>
#synthesize viewerTypeOfDescription;
// <<
#synthesize firstname;
#synthesize lastname;
// >>
- (id)initConforming {
if (self=[super init]) {
viewerTypeOfDescription=ViewerDataType_NSString;
}
return self;
}
- (NSString*)nameOfClass {
return [self className];
}
- (NSString*) dataRepresentation {
if (firstname!=nil && lastname!=nil) {
return [NSString stringWithFormat:#"%# %#", firstname, lastname];
} else if (firstname!=nil) {
return [NSString stringWithFormat:#"%#", firstname];
}
return [NSString stringWithFormat:#"%#", lastname];
}
// <<
#end
/* A Class Serial */
#interface Serial : NSObject <ViewerProtocol>
#property NSInteger amount;
#property NSInteger factor;
#end
#implementation Serial
// >>
#synthesize viewerTypeOfDescription;
// <<
#synthesize amount;
#synthesize factor;
// >>
- (id)initConforming {
if (self=[super init]) {
amount=0; factor=0;
viewerTypeOfDescription=ViewerDataType_NSNumber;
}
return self;
}
- (NSString*)nameOfClass {
return [self className];
}
- (NSNumber*) dataRepresentation {
if (factor==0) {
return [NSNumber numberWithInteger:amount];
} else if (amount==0) {
return [NSNumber numberWithInteger:0];
}
return [NSNumber numberWithInteger:(factor*amount)];
}
// <<
#end
int main(int argc, const char * argv[])
{
#autoreleasepool {
Person *duncan=[[Person alloc]initConforming];
duncan.firstname=#"Duncan";
duncan.lastname=#"Smith";
[Viewer printLargeDescription:duncan];
Serial *x890tyu=[[Serial alloc]initConforming];
x890tyu.amount=1564;
[Viewer printLargeDescription:x890tyu];
NSObject *anobject=[[NSObject alloc]init];
//[Viewer printLargeDescription:anobject];
//<< compilator claim an issue the object does not conform to protocol
}
return 0;
}
An other Example with Protocol inheritance over subClassing
typedef enum {
LogerDataType_null,
LogerDataType_int,
LogerDataType_string,
} LogerDataType;
#protocol LogerProtocol
#property size_t numberOfDataItems;
#property LogerDataType dataType;
#property void** data;
#end
#interface Loger : NSObject
+ (void) print:(id<LogerProtocol>)object;
#end
#implementation Loger
+ (void) print:(id<LogerProtocol>)object {
if ([object numberOfDataItems]==0) return;
void **data=[object data];
for (size_t i=0; i<[object numberOfDataItems]; i++) {
switch ([object dataType]) {
case LogerDataType_int: {
printf("%d\n",(int)data[i]);
break;
}
case LogerDataType_string: {
printf("%s\n",(char*)data[i]);
break;
}
default:
break;
}
}
}
#end
// A Master Class
#interface ArrayOfItems : NSObject <LogerProtocol>
#end
#implementation ArrayOfItems
#synthesize dataType;
#synthesize numberOfDataItems;
#synthesize data;
- (id)init {
if (self=[super init]) {
dataType=LogerDataType_null;
numberOfDataItems=0;
}
return self;
}
#end
// A SubClass
#interface ArrayOfInts : ArrayOfItems
#end
#implementation ArrayOfInts
- (id)init {
if (self=[super init]) {
self.dataType=LogerDataType_int;
}
return self;
}
#end
// An other SubClass
#interface ArrayOfStrings : ArrayOfItems
#end
#implementation ArrayOfStrings
- (id)init {
if (self=[super init]) {
self.dataType=LogerDataType_string;
}
return self;
}
#end
int main(int argc, const char * argv[])
{
#autoreleasepool {
ArrayOfInts *arr=[[ArrayOfInts alloc]init];
arr.data=(void*[]){(int*)14,(int*)25,(int*)74};
arr.numberOfDataItems=3;
[Loger print:arr];
ArrayOfStrings *arrstr=[[ArrayOfStrings alloc]init];
arrstr.data=(void*[]){(char*)"string1",(char*)"string2"};
arrstr.numberOfDataItems=2;
[Loger print:arrstr];
}
return 0;
}
The variable, anObject, needs to be defined in your TestProtocolsViewController class definition, the protocol is just informing you that it should be there.
The compiler errors are telling you the truth - the variable doesn't exist. #properties are just helpers after all.