我是iOS新手,我正在尝试了解一些在iOS应用中执行操作的“良好做法”。
我有一个ViewController,我将其作为应用程序启动时调用的控制器。在其中我看到了一个名为viewDidLoad的函数,我尝试修改它以检查用户是否有user_id,然后调用最终会发出异步请求以在远程数据库中管理该用户的函数。这是我的代码:
- (void)viewDidLoad
{
[super viewDidLoad];
EmailUtil *email = [EmailUtil alloc];
email = [email init];
// This is just a test call to the function that would make a remote server request
[email setEmail: @"test" andBody: @"hello"];
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
if([standardUserDefaults objectForKey:@"user_id"] == nil)
{
NSLog(@"First time");
[standardUserDefaults setBool:YES forKey:@"user_id"];
}
else
{
NSString *subject = @"subject";
NSString *body = @"bod";
NSLog(@"Not first time");
}
}
所以我在这里有一些不确定的事情。我可以调用一个函数从viewDidLoad进行远程调用会导致该函数出现问题吗?目前它没有发送远程请求。
另外,我应该在此函数结束时为我创建的对象释放内存吗?
或者我应该将此代码移动到类中的另一个位置,以便在那里使用该代码更有意义吗?
我这样称呼电子邮件对象:
[email setEmail: @"test" andBody: @"hello"];
以下是EmailUtil类的代码:
//
// EmailUtil.m
//
#import "EmailUtil.h"
@implementation EmailUtil
-(void) setEmail: (NSString *) subject andBody: (NSString *) body
{
NSString *final_url = [NSString stringWithFormat:@"http://www.my_url.com?subject=%@&body=%@",subject, body];
NSURL *url = [NSURL URLWithString:final_url];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url ];
// TODO: ok I dont really understand what this is
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
NSLog(@"On return");
NSLog(@"This is data: %@" , data);
NSLog(@"This is response: %@" , response);
NSLog(@"This is error: %@" , error);
NSLog(@"OK");
}];
}
@end
谢谢!
答案 0 :(得分:2)
你说:
所以我在这里有一些不确定的事情。可以这样的事实 我正在调用一个函数来从viewDidLoad原因进行远程调用 那个功能有问题吗?目前它没有发送遥控器 请求。
随意在viewDidLoad中进行任何调用。只要确保不做任何阻止UI的事情(例如一些冗长复杂的方法)。任何长时间运行的非UI相关任务都将在一个单独的队列中异步完成,但在不久的将来,这将是另一天。
无论是在此处执行此操作,还是在application:didFinishLaunchingWithOptions:
中执行此操作,都取决于您的UI将要执行的操作。我们需要更好地了解您的应用流程来回答这个问题。我们需要了解EmailUtil
如何呈现自己(通常这些类使用模态表示,从另一个视图控制器而不是application:didFinishLaunchingWithOptions:
开始是有意义的。)
但是,最重要的是,我个人application:didFinishLaunchingWithOptions:
总是带我去看应用程序"主要"或者"家庭"如果我想在第一次使用时提供某些内容,但没有将其作为主页面,那么我将从主视图控制器viewDidLoad
调用此页面。其他人会使用"第一次使用"来自定义application:didFinishLaunchingWithOptions:
。逻辑。这是个人偏好的问题。
另外,我应该在此函数结束时为我创建的对象释放内存吗?
内存管理的第一条规则是,您始终应该释放您拥有的任何内容(通常是您创建的任何内容),并且只释放您拥有的内容。但是,如果您正在使用ARC(我强烈建议您这样做),那么就会为您处理(对象因超出范围而被释放)。
或者我应该将此代码移动到类中的另一个位置 那些代码在那里会更有意义吗?
就个人而言,我并不是因为主视图控制器出现而让应用程序发送电子邮件并不疯狂,因为我认为这只是一个示例,而不是真正的应用程序。但是如果你正在考虑把它放在一个不同的地方,那就发送电子邮件"功能更逻辑地挂钩用户点击"发送电子邮件"按钮,而不是自行运行。
关于其他问题:
这段代码很奇怪,因为您正在创建EmailUtil
,一个本地var,设置设置一些属性,但后来没有对它做任何事情,然后让它掉出来范围。我认为你想要一些方法让这个EmailUtil
做它的东西,例如[email sendMessage]
,或任何适当的方法。
您还要创建两个本地变量subject
和body
,而不是使用它们并让它们超出范围。我认为您希望相应更新email
对象的属性,但尚未达到此目的。
您是否有理由编写自己的EmailUtil
课而不是使用MessageUI.framework
?希望EmailUtil
只是MessageUI.framework
的一个不错的包装器,或者做一些完全不同的事情,但不能复制Apple已经提供的功能。
您说该应用程序将发出异步请求以在远程数据库中管理该用户"。哇。我现在一直在做那种事情,但我不建议与服务器进行异步协调,这是一个很好的首次项目。希望当你说"最终"你的意思是"从现在开始的几个月"而不是"在接下来的一周或两周内。"看起来你仍然在基本的视图控制器和内存管理方面获得了大量的支持。您可能想看看是否可以将应用程序初始版本的功能限制为不那么雄心勃勃的东西。如果你还没有掌握一些基本技能,并尝试做一些复杂的事情,那么你最终可能会发现手上的一团糟,以后你会发现自己完全重写。所以,没有冒犯,但看看你是否可以为你的第一个真正的项目提出一些更简单的东西。或者先做几个测试应用程序。只是一个想法。
Lvsti非常正确,典型的对象创建结构是[[EmailUtil alloc] init]
。你所拥有的是等同的,但非标准的。
我知道这是一项正在进行的工作,但看起来您的setEmail:andBody:
正在设置属性并发送消息。我建议(a)为@property
和subject
提供body
个条目(这将自动生成setSubject
和setBody
方法,以及让你做email.subject = @"This is the subject of the email";
)之类的东西; (b)如果你愿意,可以使用init方便方法,例如initWithSubject:body:
,它将执行init你的对象并设置这两个属性; (c)有一个实际发送消息的单独方法。拥有一个看起来像一个二传手的东西并不是一个好习惯,它有点像一个制定者,但也可以用一种方法做更多的材料。以" set"开头的方法通常是标准的setter,iOS惯例会导致其他程序员误读你的代码(就像我刚才那样)。通过遵循一些标准的iOS约定,如果您让iOS程序员参与审阅和修改代码,将会更容易。
答案 1 :(得分:1)
您应该将此代码移动到appdelegate的应用程序:didFinishLaunchingWithOptions:方法。 来自iOS-Dev-Center
您应该使用此方法初始化您的应用程序并做好准备 它运行。在您的应用程序启动后调用它 并且已加载其主nib文件。当时这个方法是 在调用时,您的应用程序处于非活动状态。
如果你没有使用arc,那么你应该释放的东西就是EmailUtil,没有理由手动解除分配