How to call function at other class in objective-c? - ios

I am developing in Objective-C.
I create the two file call AAA.m and BBB.m.
1. In the AAA.m , I call a function readValue in BBB.m and send a NSString.
2. In the BBB.m , I receive the NSString from AAA.m , and then call the function updateState in AAA.m.
3. When the updateState in AAA.m has been called from BBB.m. It set the value from BBB.m to the UISlider.
The code is like the following:
AAA.m
#property (strong,nonatomic)BBB *bbb;
- (void)viewDidLoad
{
[self.bbb initAAA];
[self.WhiteSlider setMinimumValue:0];
[self.WhiteSlider setMaximumValue:100];
}
- (IBAction)SyncLEDState:(id)sender {
[self.bbb readValue:#"50"];
}
- (void)updateState:(NSString*)state
{
NSlog(#"state = %#",state);
self.WhiteSlider.value = [state intValue];;
}
BBB.m
#property (strong,nonatomic)AAA *aaa;
-(void)initAAA
{
self.aaa = [[AAA alloc] init];
}
-(void)readValue:(NSString*)string
{
NSlog(#"string = %#",string);
[self.aaa updateState:string];
}
I already receive the value in updateState function which called by BBB.m.
But I can not update the value of UILabel or UISlider in AAA.m.
I am sure the UISlider did not has problem.
Is BBB.m create a new AAA.m due to self.aaa = [[AAA alloc] init]; , so it did not change the value of UISlider at original AAA.m?
Did I missing something ? Thanks in advance.

BBBcreates its own private version of AAAin self.aaa that is different from the aaa in the call to its readValue:. Hence you are (presumably) updating the state of an AAA that is not displayed.
Alternatively, you could modify your current version approx. as follows:
in AAA.m:
self.bbb = [[BBB alloc] initWithAAA: self];
in BBB.m:
- (id)initWithAAA: (AAA *)aaa {
self = [super init];
if (self)
self.aaa = aaa;
return self;
}
This would make sure that both AAA and BBB refer to the same instance of AAA.

Related

Allocating two NSMutableArrays while one is an instance variable another is a property

I am new to Objective-C and maybe this question is quite stupid but I'm a little confused about it.
Suppose, I have a class and that class contains two different NSMutableArrays: library and playlists. Playlists is an instance variable while library is a property (they are for different purposes). Now, to work with library I have to alloc init it (for example, in an initialiser method). But why shouldn't I do the same for playlists?
When I try to do the same for playlists, my code stops working, but when I don't do it, it works fine (I can add objects to playlist, for example).
EDIT
The example when this happens is in the code snippets below. I have two classes Playlist and MusicCollection. MusicCollection has two arrays: library (property), which contains all songs from all playlists, added to the second array called playlists (instance variable). The code that doesn't work is this one:
-(void)addPlaylist:(Playlist *)thePlaylist {
if ([playlists indexOfObjectIdenticalTo:thePlaylist] != NSNotFound) {
NSLog(#"ADDED");
[playlists addObject:thePlaylist];
[library addObjectsFromArray:thePlaylist.mySongs];
}
}
When I have this initialisation method the code above works fine:
-(instancetype)initMusicCollectionWithName:(NSString *)nameOfPlaylist {
self = [super init];
if (self) {
self.name = nameOfPlaylist;
library = [[NSMutableArray alloc] init];
}
return self;
}
But when I have something like this, it doesn't (it just doesn't add playlists to the playlists array).
-(instancetype)initMusicCollectionWithName:(NSString *)nameOfPlaylist {
self = [super init];
if (self) {
self.name = nameOfPlaylist;
library = [[NSMutableArray alloc] init];
playlists = [[NSMutableArray alloc] init];
}
return self;
}
EDIT 2
As asked, here are the declarations for two arrays:
(library array)
#interface MusicCollection : NSObject
#property(nonatomic, copy) NSMutableArray *library;
(playlists array)
#implementation MusicCollection{
NSMutableArray *playlists;
NSRange range;
}
Could you explain why this happens, please?
Because
self.name = nameOfPlaylist;
gives a strong non-nil reference to name string as you declared it as nonatomic , copy from nameOfPlaylist parameter
so library will work if you pass it like name
-(instancetype)initMusicCollectionWithName:(NSString *)nameOfPlaylist library:(NSString*)lib{
self = [super init];
if (self) {
self.name = nameOfPlaylist;
library = lib;
}
return self;
}
wether it's instance variable or property it must be allocated
and when allocated

Using Text Field to add String to NSMutableArray

I am looking to get an NSString value from a Text Field and add it to an array, I want to build an array with many strings in it ex:
[hello, goodbye, too soon].
This is my current solution:
- (IBAction)submitButton:(id)sender {
NSMutableArray *wordArray = [[NSMutableArray alloc] init];
NSString *input = textField.text;
[wordArray insertObject:input atIndex:arrayIndex];
arrayIndex++;
}
This works for the first item in the array, but when I press submit again it reinitializes.My issue is how do I initialize the NSMutableArray to use in the button function, without having it in there so that it doesn't initialize every time. Thank you
Your are using a local array that disappears as soon as the submitButton method is finished.
Make your wordArray an instance variable and initialize it once in viewDidLoad. Then in your submitButton: method (and any others), you reference the instance variable instead of creating local arrays.
Honey's answer is almost, but not, correct.
Your code uses a local variable in your submitButton method, and creates a new, empty array each time the method gets called. Both of those things are wrong.
Honey's answer has you create a different local variable in viewDidLoad. That's also wrong.
You need to make wordArray an instance variable or property of your class. If you class is called ViewController, say, it might look like this
#interface ViewController: UIViewController;
#property (nonatomic, strong) NSMutableArray *wordArray
...
#end
And then initialize it in viewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
self.wordArray = [[NSMutableArray alloc] init];
}
Then in the rest of your program refer to self.wordArray, the property.
Here's the solution,
#implementation ViewController{
NSMutableArray *_wordArray;
}
- (void)viewDidLoad {
[super viewDidLoad];
_wordArray = [[NSMutableArray alloc] init];
}
- (IBAction)submitButton:(id)sender {
NSString *input = textField.text;
[wordArray addObject:input];
}
You was re init the array each time you make the action, which will let you always save the last value of the textfield.
but this creates an array as global variable so that you can add all the values entered in textfield.
Hope this help you :)

How to Create Dynamic Value Which Can use Entire App

Basiclly, I have a button which created value according to finish some math process like +, - , /, *. Question is when I get some value, I needed to use that value again when I press button second time. Let me explain Basicly,
When I clicked button process like,
int examplea = [txt_example.text intValue];
int exB = 5000;
int exC = exB - examplea;
This is the first time I push the button, my lastest value is exC When I input text field another value and clicked it same process will start but one difference:
int examplea = [txt_example.text intValue];
int exB = exC;
int exC ( this new value which will be calculated ) = exB - examplea;
How can I create process like this?
Something like this
in the .h file
#interface MyCalculator : NSObject
- (int) doCalculation;
#property (assign, nonatomic) int exB;
#end
in the .m file
#implementation MyCalculator
- (id) init
{
self = [super init];
if (self)
{
_exB = 5000;
}
return self;
}
- (int) doCalculation
{
int examplea = [txt_example.text intValue];
int exC = self.exB - examplea;
self.exB = exC;
return exC;
}
#end
....
MyCalculator* myCalculator = [[MyCalculator alloc] init];
...
[myCalculator doCalculation];
This isn't the full solution as there are several questions about what your code will do, but it will illustrate the principle of how to do it.
The last line is what gets called when the button is pressed.
I don't know where txt_example.text is coming from, but it might be better if that is passed to doCalculation as a parameter.

passing values string values to an object and recieving a string in return in ios

Hi a very simple app it takes in 2 arguments via 2 text boxes, and then totals them and displays them in a label called result. The idea is to have it handled via an object called brain, for which in the later part i have given the code. problem is foo is zero and when you click the button the result goes to nothing.
The plan is to use this to build a better model view architecture for a bigger app i have completed.
#import "calbrain.h"
#import "ImmyViewController.h"
#interface ImmyViewController ()
#property (nonatomic, strong) calbrain *brain;
#end
#implementation ImmyViewController
#synthesize brain;
#synthesize num1;
#synthesize num2;
#synthesize result;
-(calbrain *) setBrain
{
if (!brain) {
brain = [[calbrain alloc] init];
}
return brain;
}
- (IBAction)kickit:(UIButton *)sender {
NSString *number1 = self.num1.text;
NSString *number2 = self.num2.text;
NSString *foo;
foo = [brain calculating:number1 anddouble:number2];
self.result.text = foo;
// self.result.text = [brain calculating:self.num1.text anddouble:self.num2.text];
}
#end
#implementation calbrain
-(NSString *) calculating:(NSString *)number1 anddouble:(NSString *)number2
{
double numb1 = [number1 doubleValue];
double numb2 = [number2 doubleValue];
double newresult = (numb1 + numb2);
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
NSString *numberAsString = [numberFormatter stringFromNumber:[NSNumber n numberWithFloat:newresult]];
return numberAsString;}
Check your brain using NSLog in the (IBAction)kickit:(UIButton *)sender function. I guess you didn't initialise brain. If this is not the case, you need to provide more code.
i did just that, i came to the conclusion the setter for brain isnt working properly
i put the alloc init line of code before i needed to alloc init the brain, and it works fine, i stubbed out the setter,
i will go back and see why it wasnt overriding the setter made by properties, but interesting stuff none the less. it means i can change my actual larger app to have a cleaner more organised architecture.
thanks for your time.
Try initializing your brain object in viewDidLoad() using your setter method. You have to call setter method to get your brain object initialized.
Something like this
viewDidLoad()
{
brain = [self setBrain];
//You can also do this
brain = [[calbrain alloc] init];
}
and use that brain object in your (IBAction)kickit: method.
Hope this helps.

ios - background thread calling a property and returning nil

I am very new to IOS programing.
I've created a class, that uses a NSURLConnection to download data async.
I use a delegate that's sent across and in turn updates my father class. Part of updating the father class includes calling a UIView that has been saved in a local property.
Here are some code examples of what I mean:
myClass:
#synthesize myView = _myView;
-(void) loadMetaData
{
if(self.isMetadataLoaded)
{
[self.myView metadataLoaded];
}
else {
[_htmlLinter summarizeUrl:self.originalLink];
}
}
-(void) urlSummarized:(NSDictionary*)data
{
self.productTitle = [data objectForKey:#"title"];
self.productDescription = [data objectForKey:#"description"];
self.provider = [data objectForKey:#"provider_name"];
self.isMetadataLoaded= true;
[self.myView metadataLoaded];
}
htmlLinter:
-(void)summarizeUrl:(NSString*)url
{
NSURL* u = [[NSURL alloc] initWithString:request];
...
...
...
//removed a lot of logic that doesn't seem to be relevant
//Important to notice, that this is being called on a different thread though:
[self embedlyDidLoad:result];
}
-(void) embedlyDidLoad:(id)result
{
NSDictionary* properties = (NSDictionary*)result;
[_facilitator urlSummarized:properties];
}
The strange thing is this:
myClass doesn't remember what self.myView is when accessed through another thread.
This line the problematic one : [self.myView metadataLoaded];
it returns a valid pointer when called initially in loadMetaData,
but when I call it on another thread in urlSummarized, it is nil.
What can be causing that?

Resources