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);
}
Related
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
NSString is returning as NULL while Importing from ViewController Class
were i want to import the string variable from 1st class to second class..but its not importing
please find met code below for your reference
ViewController:
#interface ViewController : UIViewController{
NSString * string;
#property(nonatomic, retain)NSString * string;
#end
#implementation ViewController
#synthesize string;
-(IBAction) login:(id) sender{
string = #"HI";
}
class2:
#import"ViewController.h"
#interface class2 : UIViewController{
ViewController * vc;
NSString * string1;
#property(nonatomic, retain)NSString * string1;
#end
#implementation ViewController
#synthesize string1;
-(IBAction) login:(id) sender{
NSLog(#"%#",vc.string);
#end
}
Where NSLog is returning NULL!!!!
Kindly help me!
Thanks in advance
I am not clear about your code but if you want to send string from class1 to class2 then you can follow below method:
1.Declare property in class2, same as you have declare:
NSString * string1;
#property(nonatomic, retain)NSString * string1;
#synthesize string1;
2.Then in class1 where you are navigating to class2 (from where you are initializing class2) just assign your string1 the required value as follows:
class2Obj.string1 = #"Hi";
and In class2 you can access string1.
#pradeepj its returning Null because your vc instance is also Null, i am not sure how are you getting instance of vc. If you are using a UINavigationController then you can get instance of vc by using viewControllers property of UINavigationController.
The second class doesn't just automatically get a reference to the same instance of class1 where you set the string value. Your class2 needs to have a property that is set possibly from class1 that references the instance of class 1 where you set the string
//in class 1
Class2 *vc = [[Class2 alloc] init];
vc.class1 = self;
[self.navigationcontroller pushViewController:vc animated:YES];
just change:
-(IBAction) login:(id) sender{
string = #"HI";
}
to
-(IBAction) login:(id) sender{
self.string = #"HI";
}
this will retain ur variable so that you may find it elsewhere. Just be sure that you have assigned the vc variable correctly before fetching value of string variable.
this is something I have always had confusion about
I never can seem to find a good explanation, i understand inheritance, but from what i learned that is between the master class and the sublasses of them...What if i want to pass a NSString to another class thats not a subclass of the other
Heres a example:
class1.h
#interface class1 : UIViewController{
NSString *string
}
#property (nonatomic, retain) NSString *string
#end
class1.m
#implementation class1
#synthesize string;
-(void)viewDidLoad{
string = #"IM A STRING AHHH";
}
Now lets say i want to pass that string with what its equal to to another class
class2.h
#import "class1.h"
#interface class2 : UIViewController{
}
#end
class2.m
#implementation class2
//i want to use the NSString in here, how do i do that?
Thanks,
Jacob
First of all use [string retain]; in class 1.
Then, in class 2, import class1. make object of class 1 say cls1. and you can access it by cls1.string;
Smiriti's answer is right...
what else you can do is..
overrirde the init method and pass your NSString as a parameter and use it.
You can create an instance of class1 and then you can access string simply calling
[instance string];
or
instance.string
If you don't want to create an instance of class1 you may define a method such as
+(NSString*)getString;
and then call it from class2
[class1 getString];
If class 2 is loading from class 1 you can send the value as parameters.
-(id)initwithParameters:(NSString *)parameter
{
if(self == [super init])
{
// access the paramenter and store in yo u avariable
}
return self;
}
In class 1
[[class 2 alloc]initwithParameters: ]
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'>
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.