Variable in my iOS app? - ios

I can't belice I am asking this, but im very crazy with this variable stuff.
I want to save a username information. I load them at the load of my view. After this I will get the information when I click on a button.
Here is my code:
#interface SelfViewController : UIViewController
{
NSString *usernameString;
}
- (void)viewDidLoad
{
usernameString = #"test";
}
- (IBAction)goToProfileButtonPressed:(id)sender
{
NSLog(#"%#", usernameString); //CRASH BAD EXEC
}
What did I wrong????

Change your .h file to:
#interface SelfViewController : UIViewController {
    NSString *usernameString;
}
#property (retain, nonatomic) NSString *usernameString;
Then in your .m file:
#synthesize usernameString;
- (void)viewDidLoad {
     self.usernameString = #"test";
}
- (IBAction)goToProfileButtonPressed:(id)sender {
    NSLog(#"%#", self.usernameString); // "self." can be omitted, but it is best practice not to
}
- (void)dealloc {
[usernameString release];
[super dealloc];
}
The problem is that you assign usernameString to an autoreleased string object. By the time the button is pressed, usernameString has been released and has become garbage memory. By retaining it (and subsequently releasing it in -dealloc to avoid a leak) you know that it will not be prematurely released.

You need to synthesize the ivar and add it as a property. (For not-ARC compiling):
in the .h:
#interface SelfViewController : UIViewController
{
NSString *usernameString;
}
#property (nonatomic, retain) NSString *usernameString;
in the .m:
#synthesize usernameString;

Related

Cannot display array on view load

I am trying to display the contents of an array by calling a method in a different class that loops through the array and appends a string. However it is not displaying anything when i segue to that view. I have added breakpoints to check if there is anything in the array and the data is definitely being stored inside.
Is there a reason why this is happening?
Portrait class where i want all the array contents to be displayed
portrait.h
#import <UIKit/UIKit.h>
#import "Brain.h"
#interface PortraitTape : UIViewController
#property (weak, nonatomic) IBOutlet UITextView *equationView;
#property (nonatomic,strong) Brain *brain;
#end
portrait.m
#import "PortraitTape.h"
#interface PortraitTape ()
#end
#implementation PortraitTape
#synthesize brain = _brain;
#synthesize equationView;
- (Brain *) brain{
if (!_brain)_brain =[[Brain alloc]init];
return _brain;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
NSString *tape;
tape = [self.brain gettape];
equationView.text = tape;
}
Brain.m class method that hashe array and data is being inserted into. This method is called in the portrait class.
-(NSString*) gettape {
NSMutableString *tape = [[NSMutableString alloc]init];
for(NSString * myStr in _equation) {
//tape = myStr;
[tape appendFormat:#"\n%#",myStr];
}
return tape;
}

delegate respondsToSelector:selector not working

I saw a lot of this kind of questions and answers here, but couldn't find solution to my problem. I'm trying to send data from one view controller to another and use delegate. But don't know why my postDelegate doesn't responds to selector. Is something wrong with this code or what is the problem?
PostViewController.h file
#protocol GetDataDelegate <NSObject>
-(void)getPassedInfo:(NSString*)info;
#end
#interface PostViewController : UIViewController
#property (nonatomic, weak) id <GetDataDelegate> postDelegate;
#end;
PostViewController.m file
#import "PostViewController.h"
- (IBAction)postData:(id)sender {
if ([_postDelegate respondsToSelector:#selector(getPassedInfo:)]) {
[self.postDelegate getPassedInfo:#"data"];
NSLog(#"responds");
}
[self dismissViewControllerAnimated:YES completion:nil];
}
in second view controllers .h file
#import "PostViewController.h"
#interface MainViewController : UITableViewController <GetDataDelegate>
and in .m file
#implementation MainWindowTableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
PostViewController * postController = [[PostViewController alloc]init];
postController.postDelegate = self;
}
and here is delegate method:
-(void)getPassedInfo:(NSString *)info{
NSLog(#"info is %#", info);
}
You need to make postController a property or an ivar. Currently it is a local variable in the viewDidLoad method which will be deallocated after viewDidLoad completes as #CodaFi said above.
#import "PostViewController.h"
#interface MainViewController : UITableViewController <GetDataDelegate>
#property (nonatomic, strong) PostViewController *postController;
#end
Then:
- (void)viewDidLoad
{
[super viewDidLoad];
self.postController = [[PostViewController alloc]init];
self.postController.postDelegate = self;
}

How to implement a progress bar on top of UIWebView?

I am developing application for iOS7 in xcode 5. I have a view controller ADMSViewController
The .h file is as follows
#import <UIKit/UIKit.h>
#import "IMTWebView.h"
#interface ADMSViewController : UIViewController <UIWebViewDelegate,IMTWebViewProgressDelegate>
{
NSString *barcode;
NSString *vinNumber;
NSTimer *timer;
}
#property (nonatomic,retain) IBOutlet UIWebView *webView;
#property (nonatomic,retain) IBOutlet UIProgressView *progressView;
#end
The .m file is as follows
#import "ADMSViewController.h"
#import <QuartzCore/QuartzCore.h>
#implementation ADMSViewController
#synthesize webView;
#synthesize progressView;
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://google.com/"]]];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES animated:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.navigationController setNavigationBarHidden:NO animated:animated];
}
- (void)webView:(IMTWebView *)_webView didReceiveResourceNumber:(int)resourceNumber totalResources:(int)totalResources {
[self.progressView setProgress:((float)resourceNumber) / ((float)totalResources)];
if (resourceNumber == totalResources) {
_webView.resourceCount = 0;
_webView.resourceCompletedCount = 0;
}
}
- (void)viewDidUnload
{
[super viewDidUnload];
self.webView = nil;
self.progressView = nil;
}
#end
The IMTWebview.h file is as follows
#import <UIKit/UIKit.h>
#class IMTWebView;
#protocol IMTWebViewProgressDelegate <NSObject>
#required
- (void) webView:(IMTWebView*)webView didReceiveResourceNumber:(int)resourceNumber totalResources:(int)totalResources;
#end
#interface IMTWebView : UIWebView {
}
#property (nonatomic, assign) int resourceCount;
#property (nonatomic, assign) int resourceCompletedCount;
#property (nonatomic, assign) id<IMTWebViewProgressDelegate> progressDelegate;
#end
the IMTWebCiew.m file is as follows
#import "IMTWebView.h"
#interface UIWebView ()
-(id)webView:(id)view identifierForInitialRequest:(id)initialRequest fromDataSource:(id)dataSource;
-(void)webView:(id)view resource:(id)resource didFinishLoadingFromDataSource:(id)dataSource;
-(void)webView:(id)view resource:(id)resource didFailLoadingWithError:(id)error fromDataSource:(id)dataSource;
#end
#implementation IMTWebView
#synthesize progressDelegate;
#synthesize resourceCount;
#synthesize resourceCompletedCount;
-(id)webView:(id)view identifierForInitialRequest:(id)initialRequest fromDataSource:(id)dataSource
{
[super webView:view identifierForInitialRequest:initialRequest fromDataSource:dataSource];
return [NSNumber numberWithInt:resourceCount++];
}
- (void)webView:(id)view resource:(id)resource didFailLoadingWithError:(id)error fromDataSource:(id)dataSource {
[super webView:view resource:resource didFailLoadingWithError:error fromDataSource:dataSource];
resourceCompletedCount++;
if ([self.progressDelegate respondsToSelector:#selector(webView:didReceiveResourceNumber:totalResources:)]) {
[self.progressDelegate webView:self didReceiveResourceNumber:resourceCompletedCount totalResources:resourceCount];
}
}
-(void)webView:(id)view resource:(id)resource didFinishLoadingFromDataSource:(id)dataSource
{
[super webView:view resource:resource didFinishLoadingFromDataSource:dataSource];
resourceCompletedCount++;
if ([self.progressDelegate respondsToSelector:#selector(webView:didReceiveResourceNumber:totalResources:)]) {
[self.progressDelegate webView:self didReceiveResourceNumber:resourceCompletedCount totalResources:resourceCount];
}
}
#end
My issue is that the progress bar is not animating in the webview. Please help me as I am a newbie to ios development. If there is any other method to implement the same, do inform me.
Thank you in advance for your answers.
For this kind of thing, you can only really 'detect' page size by using Content-Length headers, but otherwise you can still present a loading control (like one of the moving zebra crossing type bars which doesn't show a discrete % progress but shows that activity is occurring.. or even just a UIActivityIndicator). You could try a ready-made class like http://allseeing-i.com/ASIHTTPRequest/ASIWebPageRequest too, which CAN show progress. The author states:
ASIWebPageRequests do not currently support progress tracking for an entire request with its external resources. However, progress updates from external resource requests are passed on to your delegate, so with a bit of work it may be possible to implement this yourself.

how to implement memoryReceiveWarning

i am in initial phase of development and i want to make sure i am in right direction with regards to memory management.
i have a view controller named LayoutViewController with xib.I have a custom ui-subclass with its xib named LayoutContainerView which basically contains a scrollview. I am using LayoutContainerView in LayoutViewController xib by IBOutlet.
I have an another UIView subclassed, which contains a view with background image, some labels and a transparent button with same frame as of viw.I am adding this custom controll in LayoutContainerView's scrollview.
my view controller .h looks like this:
#import <UIKit/UIKit.h>
#protocol LayoutVcRemovedProtocol;
extern const char* MyConstantKey;
#interface LayoutViewController : UIViewController
// public properties
#property (nonatomic, copy) NSString *databasePath;
#property (nonatomic, weak) id<LayoutVcRemovedProtocol> layoutVcRemovedProtocolDelegate;
#end
#protocol LayoutVcRemovedProtocol<NSObject>
-(void) layoutVcRemovedProtocolMethod;
#end
=========================
**some of relevant code of **implementation** file looks like this:**
//private stuffs goes here
const char* MyConstantKey = "MyConstantKey";
#interface LayoutViewController () <UIActionSheetDelegate, UIAlertViewDelegate>
#property(nonatomic, weak) IBOutlet LayoutContainerView *layoutContainerView;
#property(nonatomic, weak) IBOutlet UIButton *backbutton;
#property(nonatomic, weak) IBOutlet UILabel *layoutNameLabel;
#property (nonatomic, strong) UIView *baseView;
#property (nonatomic, strong) NSMutableArray *layoutModelArray;
-(IBAction)backButtonPressed;
#end
#implementation LayoutViewController
//my viewDidLoad and viewWillAppear look like this:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self adjustLayoutContainerFrameAndSetDataBasePath];
}
-(void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.layoutNameLabel.text = [Utils getLayoutName];
[self getLatestData];
}
-(void) getLatestData
{
[self setUpDataSource];
[self setUpComponentsOnLayoutScreen];
}
#pragma mark - datasource method
-(void)setUpDataSource
{`
self.layoutModelArray = (NSMutableArray *)[LAYOUTMODULE getAllLayoutData];
}`
-(void)setUpComponentsOnLayoutScreen
{`
for (int i = 0; i < self.layoutModelArray.count; i++)
{
Layout *layout = [self.layoutModelArray objectAtIndex:i];
[self drawViewWithLayoutObject:layout];
}
[self.layoutContainerView.scrollView adjustContentSize];
}
this is what i am trying to manage memory:
-(void) cleanLayoutModelArray
{
if (self.layoutModelArray != nil && self.layoutModelArray.count >0)
{
[self.layoutModelArray removeAllObjects];
}
}
-(void) cleanComponents
{
[self.layoutContainerView.scrollView.subviews makeObjectsPerformSelector:#selector(removeFromSuperview)];
}
//user events
-(void) placeOrderForLayout:(Layout *)layout
{
[DELEGATE showLandscapeLoading];
//web service COMMUNICATION HERE here
OrderModule *oModule = [OrderModule sharedModule];
NSDictionary *requestDictionary = [NSDictionary dictionaryWithObjectsAndKeys:oModule.currentOrder.mOrderId,#"order_id",oModule.currentOrder.mPosId,#"pos_id",[Utils currentDate],#"book_date", layout.componentId, #"component_id", nil];
BOOL status = [LAYOUTMODULE placeComponentOrderThroughAPI:requestDictionary];
if (status == TRUE)
{
[self performCleanUp];
[self getLatestData];
}
[DELEGATE stopLandscapeLoading];
}
help me or any suggestion for:
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
what ever i try in memoryWarningDelegate view controller becomes black screen.
You've got a lot of #properties marked 'weak' in your code - when you mark things as weak, that means that something else is keeping track of whether it should still exist. Here you're doing it with IBOutlet items, which your controller should be keeping track, so they should be marked 'strong,' not weak. I'd review all your usage of 'weak' in this. Also refer to Apple's excellent doc on memory management. ARC will be handling most of your memory management for you. Usually, the only thing you need to do in didReceiveMemoryWarning, is to set to nil anything that's a large object, say a video or webpage you can reload if the user needs it again. Often, there's not much that you can free up at this time in your typical view. Note also that iOS devices have a fairly substantial memory footprint these days, so you should not worry about small data structures remaining resident in memory as long as they have the potential to be needed again. If you're having out of memory issues, I'd run with instruments and check for leaks.

Issue passing object to NSMutableArray in AppDelegate

I'm having trouble making a shopping cart sort-of concept in my app. I have my AppDelegate (named ST2AppDelegate) that contains an NSMutableArray called myCart. I want RecipeViewController.m to pass an NSString object to myCart, but every time I pass it the NSString and use NSLog to reveal the contents of the array, it is always empty.
Can anyone please tell me what I am doing wrong? I have worked on this code for days, and there is a line of code in which I don't understand at all what's going on (in the RecipeViewController.m, labeled as such).
Any help would be so appreciated... I'm just a beginner. Here are the relevant classes:
ST2AppDelegate.h:
#import <UIKit/UIKit.h>
#interface ST2AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) NSMutableArray* myCart;
- (void)addToCart:(NSString*)item;
- (void)readCartContents;
#end
ST2AppDelegate.m:
#import "ST2AppDelegate.h"
#implementation ST2AppDelegate
#synthesize myCart;
// all the 'applicationDid...' methods...
- (void)addToCart:(NSString *)item
{
[self.myCart addObject:item];
}
- (void)readCartContents
{
NSLog(#"Contents of cart: ");
int count = [myCart count];
for (int i = 0; i < count; i++)
{
NSLog(#"%#", myCart[count]);
}
}
#end
RecipeDetailViewController.h:
#import <UIKit/UIKit.h>
#import "ST2AppDelegate.h"
#interface RecipeDetailViewController : UIViewController
#property (nonatomic, strong) IBOutlet UILabel* recipeLabel;
#property (nonatomic, strong) NSString* recipeName;
#property (nonatomic, strong) IBOutlet UIButton* orderNowButton;
- (IBAction)orderNowButtonPress:(id)sender;
#end
RecipeDetailViewController.m:
#import "RecipeDetailViewController.h"
#implementation RecipeDetailViewController
#synthesize recipeName;
#synthesize orderNowButton;
// irrelevant methods...
- (IBAction)orderNowButtonPress:(id)sender
{
// alter selected state
[orderNowButton setSelected:YES];
NSString* addedToCartString = [NSString stringWithFormat:#"%# added to cart!",recipeName];
[orderNowButton setTitle:addedToCartString forState:UIControlStateSelected];
// show an alert
NSString* addedToCartAlertMessage = [NSString stringWithFormat:#"%# has been added to your cart.", recipeName];
UIAlertView* addedToCartAlert = [[UIAlertView alloc] initWithTitle:#"Cart Updated" message:addedToCartAlertMessage delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[addedToCartAlert show];
// add to cart (I don't understand this, but it works)
[((ST2AppDelegate*)[UIApplication sharedApplication].delegate) addToCart:recipeName];
// read cart contents
[((ST2AppDelegate*)[UIApplication sharedApplication].delegate) readCartContents];
}
#end
You need to initialize myCart when your application launches:
self.myCart = [[NSMutableArray alloc] init];
otherwise you are just attempting to add objects to a nil object which while it won't throw an exception because of the way objective-c handles nil objects it will not function as expected until you initialize it.
Do you ever initalize the shopping cart variable?
Try doing lazy instantiation.
-(NSMutableArray *) myCart{
if (!_myCart){
_myCart = [[NSMutableArray alloc] init];
}
return _myCart;
}
This way you will know it will always get allocated. Basically, this method makes it so that whenever someone calls your classes version of the object it checks to see if that object has been allocated and then allocates it if it has not. It's a common paradigm that you should employ with most of your objects.
This method should go in the app delegate (where the object was declared).

Resources