Im not sure you understand. I need to declare an NSMutableArray and then be able to access (run instance methods) a single instance of it from anywhere in the application.
if you mean in multiple view controllers, make a singleton and declare it there
I would use subclasses
Code:
//say your .h and .m file is named "View"
//in the .h file declare all your variables and methods
//this code goes under . h file
@interface View: ViewController{
NSMutableArray *Array
}
@end
@interface View (subclass1...)
//methods are only allowed under the subclasses no variables
@end
@interface View (subclass2...)
//methods are only allowed under the subclasses no variables
@end
Code:
//this code goes under a new .m file
//not the .m file of "View"
@implementation View (subclass1)
//each subclass gets it own .m file
//and you can use every and any variable in any subclass globally from the "View" .h file
@end
@implementation View (subclass2)
//each subclass gets it own .m file
//and you can use every and any variable in any subclass globally from the "View" .h file
@end
The way to declare a global is to declare it outside of any @interface...@end block, and to define in outside of any @implementation...@end block, as in:
Code:
//this code goes under some .h file (it doesn't matter which one)
extern NSMutableArray *globalArray;
@interface (of some class - it doesn't matter which one)
...
@end
Then define globalArray as in:
Code:
NSMutableArray *globalArray;
@implementation (any, it doesn't matter which one)
...
@end
And then, somewhere where you are sure it will only be executed once:
Code:
globalArray = (some alloc-type of NSMutable Array creation method, retaining)
Now you have a singleton NSMutableArray you can access from anywhere. Just don't ever release it. It's memory will be reclaimed automatically when your app closes.
I have been reading your reply to this post and would like to use it in my App.
What I am trying to do is read the content of a record held in an SQLite table and use the result in a number of views. The SQLite result is currently written into an array. At the moment I display the result in a UIScrollView and it works fine but the amount of scrolling is becoming far to long.
I thought I would split the result between separate views. Reading your reply within the post I thought I would try and use a global array.
In the .h I have made a change from "NSMutableArray *countries" which was inside of the @interface...@end block to "extern NSMutableArray *countries;" which is now outside of the @interface...@end bloc. I have also declared "extern NSMutableArray *countries;" before the @implementation section in the .m file.
The part I am not clear about is:
Code:
globalArray = (some alloc-type of NSMutable Array creation method, retaining)
Can you advise me how to implement my array in to this statement so I can use it in other views.
Many thanks for any advice and help you can provide.
__________________
Many thanks, keep safe and well.
from "NSMutableArray *countries" which was inside of the @interface...@end block to "extern NSMutableArray *countries;" which is now outside of the @interface...@end block
you are saying that countries, which used to be an instance variable of the class, is now a global variable. So countries is what you want to use instead of globalArray.
Next, you should not use "extern" in the .m file. "extern" is only for the declaration in the .h file, not for the actual variable definition in the .m file.
Finally, you already created countries and it is retained (because you used alloc and did not release it).
So if you take away that one unnecessary extern, then you would have the setup you need to make countries a global NSMutableArray. To access it in other views, only need to import the .h file that declares countries into the .m file of those views.
I should warn you that using a global variable like this invites problems if you are careless. Remember that countries is not actually the NSMutableArray itself. It is just a pointer to that NSMutableArray. Like all Objective-C objects, this object can only be accessed through pointers. And the memory that it points to needs to be dynamically managed. Normally this dynamic memory management is taken care of for you when you make a property of an object.
By looking at your code, I see that you set countries in response to a didSelectRowAtIndexPath. Therefore you might set countries more than once. When you do that, the old NSMutableArray that countries used to point to becomes leaked memory, unless you first release it. This would have been handled automatically for you if you were content to use properties and the standard retaining setter that comes with it. But by implementing a global variable, you have abandoned the use of properties. So you have to do the work that the properties would have done for you automatically. If you really understand the retain/release system and are committed to taking the care needed to release dynamically allocated memory at just the right time, then you can make this work. But this is not normally done.
OK, I have done my best to warn you against using a global variable as a pointer to a NSMutableArray. So the choice is up to you.
Many thanks for such a details response. After reading tier reply I think I need to look at how I am going the get the result I need in another way.
Because "countries" will be set more than once your right in saying it's not the way to do it. The only reason I was looking at using a global array is because I cannot think of any other way to retain the variables in each of the views.
I need to rethink the whole process.
Again, many thanks for your advice.
__________________
Many thanks, keep safe and well.
From what I have read, "and since I started trying to learn Objective C, which was back in March, I've done a lot of reading but not enough by the look of it" your suggestion is a great idea. The only problem I have is I am not sure how to implement it.
Do you have the time to show me the syntax I should use to make the "countries" array a property of the App delegate and how I would make a call to it from a UIView.
I think if I can get over this issue I may be home and dry.
Again, many thanks in advance.
__________________
Many thanks, keep safe and well.
See the end of my tutorial on globals here. Just use NSMutableArray countries instead of NSString userName. And never set the value of countries except with the setter:
I have a file which reads my SQL data and creates an ARRAY containing the record requested by the user. A part of the file is below:
Code:
// Create a new country object with the data from the database
Country *country = [[Country alloc] initWithName:aName countryName:aCountry capitalCity:aCapital
firstLang:aLanguageF secondLang:aLanguageS voltage:aVoltage freq:aFreq dialCode:aDialCode
currencyCode:aCurrencyCode currencyName:aCurrencyName currencySymbol:aCurrencySymbol
phonePolice:aPhonePolice phoneMedical:aPhoneMedical phoneFire:aPhoneFire countryFlag:aCountryFlag
countryKey:aCountryKey countryOutletType:aCountryOutlet
timeZone1:atimeZone1 timeZone2:atimeZone2 timeZone3:atimeZone3];
// Add the country object to the countries Array
[countries addObject:country];
appDelegate.countries = countries;
[country autorelease];
The part I am struggling with is assigning the content of the ARRAY to the "appDelegate.countries = countries". I know this is because I don't know how this is done even thou I have read and re-read your tutorial. Basically I am having a very thick head time.
Can you help me advance this issue a little further.
__________________
Many thanks, keep safe and well.
I have gotten a little further, I now have the following in the file which reads the country record in to the array. I have changed he name of the array from countries to countriesList to avoid a clash with another var.
Code:
// Create a new country object with the data from the database
Country *country = [[Country alloc] initWithName:aName countryName:aCountry capitalCity:aCapital
firstLang:aLanguageF secondLang:aLanguageS voltage:aVoltage freq:aFreq dialCode:aDialCode
currencyCode:aCurrencyCode currencyName:aCurrencyName currencySymbol:aCurrencySymbol
phonePolice:aPhonePolice phoneMedical:aPhoneMedical phoneFire:aPhoneFire countryFlag:aCountryFlag
countryKey:aCountryKey countryOutletType:aCountryOutlet
timeZone1:atimeZone1 timeZone2:atimeZone2 timeZone3:atimeZone3];
// Add the country object to the countries Array
[countries addObject:country];
iTravelv113AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
appDelegate.countriesList = countries;
NSLog(@"The contents of countriesList = %@",appDelegate.countriesList);
[country autorelease];
The App complies without error but the output of the NSLog is:
2010-07-31 20:47:52.163 iTravelv113[2983:207] Database Successfully Opened
2010-07-31 20:47:52.165 iTravelv113[2983:207] The contents of countriesList = (
"<Country: 0x764a710>"
)
I am not to sure what this is telling me. Can you throw any light on the output.
__________________
Many thanks, keep safe and well.
but I am getting the following error:
"Accessing unknown setAcountryName class method, Object cannot be set, either readonly property or setter cannot be found".
Can you see anything I have missed.
__________________
Many thanks, keep safe and well.
acountryName is not a property of UITextView. Why is UITextView there?
That's a good question and to be truthful I don't know. What I was trying to do is make the "acountryName" available so I could eventually use it in a view.
Assuming all the other code is correct, How do I call the content of the "countries" array so it can be used the the view I am working on.
I know I'm a pain in the neck, sorry. But I am learning fast, I think.
__________________
Many thanks, keep safe and well.