免责声明:我是iOS的新用户,请随时告诉我我的整个方法是错误的。我只要求您解释原因-我的目标是学习(当然,也要解决这个问题)。
...
大家好,我是iOS编程的新手,在尝试解决了几个小时的问题后,我的无知和可可缺乏的经验使我得到了最大的收获。希望我能在这里找到一些帮助。
我有一个简单的TableView应用程序,正在将其用作正在开发的大型应用程序的沙箱。我现在要实现的功能是TableView单元格(即cell.detailTextLabel.text)中字幕文本的伪实时更新。
为了使您更好地了解目标,我正在努力做到这一点,以便用户可以点击TableView单元格,并且“秒表”样式计时器开始在字幕文本中进行计数。
但是我无法弄清楚如何更新cell.detailTextLabel.text。A)从我的计时器方法内部(它说未声明tableView)和B)以一种反复刷新单元格的方式让用户看到一个“ Activity ”计时器。
因此,这是一些代码(所有这些现在都在RootViewController中。最终,我想为诸如定时器之类的功能创建单独的类,但我只想让事情先开始工作)。
我还应该补充一点,在此类中,我现在有很多全局变量(“接口?”)。它使实验变得更容易,但是如果这可能导致某些问题,请告诉我。我仍在学习如何来回传递对象/变量/等。
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
self.runTimerFunctions;
}
- (void) runTimerFunctions {
start = CFAbsoluteTimeGetCurrent();
timerRunning = YES;
timer = [NSTimer scheduledTimerWithTimeInterval: 0.01 target:self selector:@selector(targetMethod:) userInfo:nil repeats:YES];
}
- (void)targetMethod: (NSTimer *)theTimer {
// NOTE TO SELF -- right now I've got hours, minutes, seconds, etc as global variables. But that may be unnecessary.
CFAbsoluteTime end = CFAbsoluteTimeGetCurrent();
CFAbsoluteTime timeDelta = end-start;
int integerSecs = timeDelta;
int integerCentiSecs = timeDelta * 100;
hundredths = integerCentiSecs % 100;
NSString *hundredthsString = [NSString stringWithFormat:@"%02i", hundredths];
seconds = integerSecs % 60;
NSString *secondsString = [NSString stringWithFormat:@"%02i", seconds];
minutes = (integerSecs / 60) % 60;
NSString *minutesString = [NSString stringWithFormat:@"%02i", minutes];
// Now combine these value strings into the single liveTimer string
liveTimer = [NSString stringWithFormat:@"%@:%@.%@", minutesString, secondsString, hundredthsString];
}
cell.textLabel.text = @"Name";
NSLog(@"liveTimer value is %@", liveTimer);
cell.detailTextLabel.text = liveTimer;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
self.runTimerFunctions;
[tableView reloadData];
最佳答案
首先,一个小虫子...liveTimer = [NSString stringWithFormat:@"%@:%@.%@", minutesString, secondsString, hundredthsString];
这可能是为什么在调用reload tableView时崩溃的原因。
您实际上想要:
要么:
self.liveTimer = [NSString stringWithFormat:@"%@:%@.%@", minutesString, secondsString, hundredthsString];
[liveTimer release];
liveTimer = [[NSString stringWithFormat:@"%@:%@.%@", minutesString, secondsString, hundredthsString] retain];
[liveTimer release];
liveTimer = [[NSString alloc] initWithFormat:@"%@:%@.%@", minutesString, secondsString, hundredthsString];
stringWithFormat:...返回一个自动释放的字符串,这意味着它将在运行循环的当前旋转结束时被释放。这将导致liveTimer基本上在函数完成后指向未定义的内存。使用self.liveTimer而不是liveTimer会导致调用合成的setter方法,而不是直接设置变量,这会导致对象在设置字符串时保留其字符串(假设您已经设置了live timer属性以保留该字符串,如下所示) :@property (nonatomic, retain) NSString *liveTimer;上面列出的其他两个选择都释放了旧版本的字符串,然后保留了新的字符串并进行设置,然后直接设置了变量。第二个是愚蠢的(它绕行创建字符串,自动释放它,然后再次保留它。)- (void)targetMethod: (NSTimer *)theTimer的末尾,您将需要实际更新当前存在的表单元格。假设tableCell位于第0节的第0行:-(void)targetMethod: (NSTimer *)theTimer {
// Everything you already had here, then...
NSIndexPath *cellIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
UITableViewCell *currentCell = [tableView cellForRowAtIndexPath:cellIndexPath];
// Returns the cell that's currently in the tableview at this location
currentCell.detailTextLabel.text = self.liveTimer;
}
cellForRowAtIndexPath:将返回nil,而currentCell.detailTextLabel.text = self.liveTimer;将不执行任何操作(即,没有错误,实际上什么也没有)。UITableViewController?如果是这样,只需在当前使用tableView的任何地方使用tableViewControllerVariableName.tableView。您的RootViewController(所有这些代码都在其中)是UITableViewController吗?如果是这样,请在您当前调用tableView的任何地方调用self.tableView。如果没有,则将tableView / tableViewController分配到哪里?发布您的头文件可能有助于清除问题...liveTimer = [NSString stringWithFormat:@"%@:%@.%@", minutesString, secondsString, hundredthsString];
self.liveTimer = [NSString stringWithFormat:@"%@:%@.%@", minutesString, secondsString, hundredthsString];
self.前缀(或就此而言,anyObject.)告诉编译器“我在这里真正想做的就是为liveTimer属性调用accessor方法”。编译器实质上将上述行替换为:[self setLiveTimer:[NSString stringWithFormat:@"%@:%@.%@", minutesString, secondsString, hundredthsString]];
@synthesize liveTimer;,因此编译器还会自动为您创建-(void)setLiveTimer:(NSTimer *)timer和-(NSTimer *)liveTimer方法。他们看起来像这样:-(void)setLiveTimer:(NSTimer *)newLiveTimer
{
[liveTimer release]; // This is the old value. It may be nil, which is fine. Calling methods on nil objects in objective-c is just be a noop, not a crash.
liveTimer = [newLiveTimer retain];
}
-(NSTimer *)liveTimer
{
return liveTimer;
}
self.liveTimer时,setLiveTimer:方法与对象一起调用,旧对象(如果有的话)被释放,而新对象被保留。[NSString stringWithFormat:...]返回一个自动释放的对象。当控件从程序的代码返回到苹果提供的运行循环代码后,自动释放的对象将被释放。它们或多或少是一种便利,因此我们不必在这里和那里一两次使用所有的小对象release。 (例如,想象一下,如果必须释放使用@“”语法创建的每个字符串,那将是多么繁琐的工作。)stringWithFormat:返回一个自动释放的对象,因为按照惯例,名称不以alloc开头的方法或copy总是返回自动释放的对象。据说像这样的方法“贩卖”了一个对象。我们可以在不久的将来使用这些对象,但是我们不能“拥有”它(即,在将控制权交还给系统之后,我们不能指望它在那里。)如果我们想获得出售对象的所有权,我们必须在其上调用[object retain],然后它将一直存在,直到我们显式调用[object release]或[object autorelease]为止;如果在不通过将变量更改为其他名称而丢失对它的引用之前,不对它调用release或autorelease,我们会泄漏它。[[NSString alloc] initWithFormat:对比。此方法“创建”一个对象。我们拥有它。同样,它将一直存在,直到我们显式调用[object release]为止。liveTimer设置为新字符串,但是该字符串已自动释放,一旦- (void)targetMethod: (NSTimer *)theTimer返回,控件便立即返回到系统的运行循环代码,并且该字符串已被释放。这意味着liveTimer指向内存中的某个随机点,该点在某一时刻包含了您的字符串对象,但现在包含了其他东西-未定义的东西。当您在内存中的那个随机位置调用方法时,它崩溃了。[NSTimer scheduledTimerWithTimeInterval:target:selector:]是一个特例。计时器会一直保留直到触发为止,这就是代码的那部分起作用的原因。没人真正知道NSTimer为什么会得到异常;这真是令人困惑,它被NExT遗留下来了。天-90年代初编写的代码,对某人来说似乎是个好主意。)self.liveTimer或self.timer或self.whatever?或多或少。您通常希望保留新对象并释放旧对象。唯一的例外之一是,如果您使用[[Object alloc] init]“创建”一个对象,则该对象已经具有保留计数1,在这种情况下,使用self.语法将第二次保留该对象,即可能不是您想要的。 (尽管,如果您之前设置了self.liveTimer =,然后在代码中稍后使用liveTimer =,则第一个字符串将被泄漏,因为从未发布过该字符串。决定执行该方法的方式并不总是那么琐碎。)关于objective-c - 如何在NSTimer循环中刷新TableView Cell数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5427196/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象