我需要在我的iOS应用程序中编写一个lib.
该陈述应该是预处理定义为:
myObject ...
#if ARC
// do nothing
#else
[myObject release]
#endif
Run Code Online (Sandbox Code Playgroud)
或运行时过程:
if (ARC) {
// do nothing
} else {
[myObject release];
}
Run Code Online (Sandbox Code Playgroud)
我能怎么做?
请帮我!谢谢.
在编写接受块作为参数的方法时,是否需要执行任何特殊操作,例如在执行块之前将块复制到堆中?例如,如果我有以下方法:
- (void)testWithBlock:(void (^)(NSString *))block {
NSString *testString = @"Test";
block(testString);
}
Run Code Online (Sandbox Code Playgroud)
block在打电话或输入方法之前,我应该做些什么吗?或者上面是使用传入块的正确方法?另外,以下调用方法的方法是正确的,还是应该在传递之前对块执行某些操作?
[object testWithBlock:^(NSString *test){
NSLog(@"[%@]", test);
}];
Run Code Online (Sandbox Code Playgroud)
在哪里做我需要复制块?如果我不使用ARC,这会有什么不同?
更新:这已在iOS 6.1 DP3 SDK中修复.
我使用默认版本构建配置使用ARC构建时,我已经跟踪了一个使用后释放崩溃(调试似乎工作正常).在具有非常量条件的if-scope中创建对象,将其分配给范围外部的变量,然后仅使用Objective-C数组或字典文字引用该变量时,会发生此问题.
这是我设法找到的最小的可重复的案例:
void test(BOOL arg)
{
id obj = nil;
if (arg) {
obj = [NSObject new];
}
// obj already deallocated here
@[obj];
// but using NSArray works
//[NSArray arrayWithObject:obj];
// @[obj] works if obj is referenced i.e. by NSLog print out
//NSLog(@"%@", obj);
}
int main(int argc, const char * argv[])
{
@autoreleasepool {
test(YES);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我使用zombie对象构建并运行它时,我收到以下错误消息:
-[NSObject retain]: message sent to deallocated instance 0x100109100
Run Code Online (Sandbox Code Playgroud)
正如我在代码中评论的那样,如果obj以其他方式引用它,它可以正常工作,例如使用NSLog或使用 …
如果我向弱对象发送消息会怎样?发送消息是否拥有该对象并将其保存在内存中直到返回?
我在考虑这种模式:
__weak MyObject *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf doSomeAction];
});
Run Code Online (Sandbox Code Playgroud)
假设weakSelf在发送消息时为非零,是否可以在doSomeAction工作时解除分配,或者保证在doSomeAction返回之前保持有效?
我试图从NSProxy的forwardInvocation中的NSInvocation获取块参数:这是正确的语法吗?它会泄漏内存吗?
typedef void(^SuccessBlock)(id object);
void *successBlockPointer;
[invocation getArgument:&successBlockPointer atIndex:index];
SuccessBlock successBlock = (__bridge SuccessBlock)successBlockPointer;
Run Code Online (Sandbox Code Playgroud)
或者我应该使用?
typedef void(^SuccessBlock)(id object);
SuccessBlock successBlock;
[invocation getArgument:&successBlock atIndex:index];
Run Code Online (Sandbox Code Playgroud)
那些像对象一样的其他参数类型呢?
__unsafe_unretained id myObject = nil; // I don't think this could be __weak? Is that correct?
[invocation getArgument:&myObject atIndex:index];
Run Code Online (Sandbox Code Playgroud)
我是否必须做其他事情以正确释放分配的内存?
提前致谢.
在ARC管理下使用Delphi for iOS终止线程的正确方法是什么?
举个简单的例子:
TMyThread = class(TThread)
protected
procedure Execute; override;
public
destructor Destroy; override;
end;
TForm2 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
FThread: TMyThread;
public
end;
{ TMyThread }
destructor TMyThread.Destroy;
begin
ShowMessage('Destroy');
inherited Destroy;
end;
procedure TMyThread.Execute;
begin
Sleep(5000);
end;
{ TForm2 }
procedure TForm2.Button1Click(Sender: TObject);
begin
FThread := TMyThread.Create(TRUE);
FThread.FreeOnTerminate := TRUE;
FThread.Start;
end;
procedure TForm2.Button2Click(Sender: TObject);
begin
ShowMessage(FThread.RefCount.ToString);
end;
procedure TForm2.Button3Click(Sender: TObject);
begin
FThread …Run Code Online (Sandbox Code Playgroud) autorelease用于返回的函数对象,因此调用者不会获得所有权,被调用者将来会释放该对象.
但是,ARC能够计算调用者的所有权并在使用后释放它,也就是说,它可以像C++中的智能指针一样行为.使用ARC,它可以摆脱自动释放,因为自动释放是非确定性的.
我问这个问题的原因是我确实看到返回的对象在ARC中比非ARC代码更早地调用dealloc.这让我认为ARC可以像Smart Pointer一样,并且可以使autorelease无用.这是真的还是可能的?我唯一可以考虑自动释放有用的是多线程或网络代码,因为在对象传递时计算所有权可能并不容易.
谢谢你的想法.
这是一个新的编辑,使事情清楚:
与自动释放
+ (MyClass*) myClass
{
return [[[MyCClass alloc] init] autorelease];
}
- doSomething
{
MyClass *obj = [MyClass myClass];
}
Run Code Online (Sandbox Code Playgroud)
使用ARC:
+ (MyClass*) myClass
{
return [[MyCClass alloc] init]; // no autorelease
}
- doSomething
{
MyClass *obj = [MyClass myClass];
// insert [obj release]
}
Run Code Online (Sandbox Code Playgroud)
所以,我们真的不需要自动释放.
memory-management reference-counting objective-c ios automatic-ref-counting
我尝试在我的项目中导入解析框架.我确定我的项目很受欢迎,但是我找不到任何关于它是否是"电弧敏感"的信息.我的项目是基于弧的.
这是我得到的错误:
Undefined symbols for architecture i386:
"_SCNetworkReachabilityCreateWithName", referenced from:
-[PFCommandCache init] in Parse(PFCommandCache.o)
+[PFInternalUtils(Reachability) isParseReachable] in Parse(PFInternalUtils.o)
"_SCNetworkReachabilityGetFlags", referenced from:
___22-[PFCommandCache init]_block_invoke in Parse(PFCommandCache.o)
+[PFInternalUtils(Reachability) isParseReachable] in Parse(PFInternalUtils.o)
"_SCNetworkReachabilityScheduleWithRunLoop", referenced from:
-[PFCommandCache init] in Parse(PFCommandCache.o)
"_SCNetworkReachabilitySetCallback", referenced from:
-[PFCommandCache init] in Parse(PFCommandCache.o)
"_SCNetworkReachabilityUnscheduleFromRunLoop", referenced from:
-[PFCommandCache dealloc] in Parse(PFCommandCache.o)
"_SecItemAdd", referenced from:
+[PFInternalUtils saveToKeychain:data:] in Parse(PFInternalUtils.o)
"_SecItemCopyMatching", referenced from:
+[PFInternalUtils loadFromKeychain:] in Parse(PFInternalUtils.o)
"_SecItemDelete", referenced from:
+[PFInternalUtils saveToKeychain:data:] in Parse(PFInternalUtils.o)
+[PFInternalUtils deleteFromKeychain:] in Parse(PFInternalUtils.o)
"_UTTypeCopyPreferredTagWithClass", referenced from:
-[PFFile getMimeType] …Run Code Online (Sandbox Code Playgroud) (但这个问题完全不同)
这个非ARC代码示例设置一个基于GCD的计时器,它为dispatch_source_t对象调用dispatch_release:
__block BOOL done = NO;
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
if (timer) {
uint64_t milliseconds = 100ull;
uint64_t interval = milliseconds * NSEC_PER_MSEC;
uint64_t leeway = 10ull * NSEC_PER_MSEC;
__block typeof(self) _self = self;
dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), interval, leeway);
dispatch_source_set_event_handler(timer, ^{
//[_progressBar setProgress:exportSession.progress animated:YES];
if (done) {
dispatch_source_cancel(timer);
dispatch_release(timer);
_self.exportingMovieLabel.hidden = YES;
_self.exportingProgress.hidden = YES;
}
});
dispatch_resume(timer);
}
Run Code Online (Sandbox Code Playgroud)
我了解到您不必在ARC下发布队列对象.但其他GCD对象如调度源?
objective-c grand-central-dispatch ios automatic-ref-counting
我曾经像这样将NSError强制转换为CFErrorRef并在SMJobBless中使用它
NSError *error
BOOL removed = SMJobRemove(kSMDomainSystemLaunchd,
(CFStringRef) daemonBundleID,
auth,
true,
(CFErrorRef*) &error);
if (!removed) {
NSLog(@"Failed to remove existing PacketTool");
[NSApp presentError: error];
}
Run Code Online (Sandbox Code Playgroud)
由于我在ARC中遇到错误,"ARC禁止使用指向'CFErrorRef'的Obj-C指针的间接指针",我改变并决定做相反的事情
CFErrorRef *cfError = nil;
BOOL blessed = SMJobBless(kSMDomainSystemLaunchd, (__bridge CFStringRef)daemonBundleID,
auth,
cfError);
if (!blessed) {
NSError *error = (__bridge NSError *)cfError;
NSLog(@"Failed to bless PacketTool: %@", error);
[NSApp presentError: error];
return FALSE;
}
Run Code Online (Sandbox Code Playgroud)
现在我有一个"不兼容的类型转换'CFErrorRef'到NSError*"与__bridge强制转换
我能做什么?
更新:感谢Greg,正确的代码现在是:
CFErrorRef cfError = nil;
BOOL blessed = SMJobBless(kSMDomainSystemLaunchd,
(__bridge CFStringRef) daemonBundleID,
auth,
&cfError);
if (!blessed) {
NSError *error …Run Code Online (Sandbox Code Playgroud) ios ×7
objective-c ×5
clang ×1
cocoa ×1
delphi ×1
delphi-xe4 ×1
frameworks ×1
iphone ×1
llvm ×1
nsinvocation ×1
xcode ×1